About this primer
Ever since the first genome-wide association study (GWAS) on age-related macular degeneration, and the promise of personalized medicine in the wake of the Human Genome Project, large-scale genetic association studies hold significant sway in contemporary health research and drive drug-development pipelines. In the past 2 decades, researchers delved into GWAS, aiming to unveil genetic variations linked to both human traits, such as the color of your eyes, and rare and common complex diseases. These findings serve as crucial keys to unravel the intricate mechanisms underlying diseases, shedding light on whether the correlations identified in observational studies between risk factors and diseases are truly causal.
These studies have ushered in an exciting era where many researchers thrive on developing new methods and bioinformatic tools to parse ever-growing large datasets collected large population-based biobanks. However, the analyses of these data are challenging and it can be daunting to see the forest for tree among the many tools and their various functions. Enter A Practical Primer in Human Complex Genetics. This GitBook was originally written back in 2022 for the Genetic Epidemiology course organized by the Master Epidemiology of Utrecht University. This practical guide will teach you how to design a GWAS, perform quality control (QC), execute the actual analyses, annotate the GWAS results, and perform further downstream post-GWAS analyses. Throughout the book you’ll work with ‘dummy’, that is fake, data, but in the end, we will use real-world data from the first release of the Welcome Trust Case-Control Consortium (WTCCC) focusing on coronary artery disease (CAD).
A major component of modern-day GWAS is genetic imputation, but for practical reasons it is not part of this book. However, I will provide some pointers as to how to go about do this with minimal coding or scripting experience. Likewise, the courses does not cover the aspects of meta-analyses of GWAS, but some excellent resources exist to which I will direct. As this practical primer evolves, these and other topics may find their place in this book.
I should also point out that emphasis of this book is on it being a practical primer. It is intended to provide some practical guidance to doing GWAS, and while theory is important, I will not cover this. Again, some very useful and excellent work exists to which I will point you, but I really want you to learn - and understand the theory - by doing.
So, although originally crafted as a companion for the course, this practical guide stands on its own as a comprehensive resource for diving into all facets of doing a GWAS — save for experimental follow-up, of course 😉.
I can imagine this seems overwhelming, but trust me, you’ll be okay. Just follow this practical. You’ll learn by doing and at the end of the day, you can execute a GWAS independently.
Ready to start?
Some background reading
Standing on the shoulders of giants, that’s what this book and I do. I want to acknowledge some great work that has helped me tremendously and, really, this book wouldn’t exist without this awesome work. So, I do want to give you some background reading. Is it a prerequisite? No, not really. For starters, the course covers most and you’ll learn as you go. And if you didn’t come here through the course, you’ll be fine just the same. That said, it’s a always good idea to get familiar with these works as you move forward on your path towards your first GWAS - in fact, I had these printed out with markings and writings all over them as I executed my first GWAS, and they’ve been great as a reference many times after.
Large parts of this work are based on four awesome Nature Protocols from the Zondervan group at the Wellcome Center Human Genetics.
- Zondervan KT et al. Designing candidate gene and genome-wide case-control association studies. Nat Protoc 2007.
- Pettersson FH et al. Marker selection for genetic case-control association studies. Nat Protoc 2009.
- Anderson CA et al. Data QC in genetic case-control association studies. Nat Protoc 2010.
- Clarke GM et al. Basic statistical analysis in genetic case-control studies. Nat Protoc 2011.
An update on the community standards of QC for GWAS can be found here:
- Laurie CC et al. Quality control and quality assurance in genotypic data for genome-wide association studies. Genet Epidemiol 2010.
With respect to imputation and meta-analyses of GWAS you should also get familiar with the following two works:
- Marchini, J. and Howie, B. Genotype imputation for genome-wide association studies. Nat Rev Genet 2010
- de Bakker PIW et al. Practical aspects of imputation-driven meta-analysis of genome-wide association studies. Hum Mol Genet 2008.
- Winkler TW et al. Quality control and conduct of genome-wide association meta-analyses. Nat Protoc 2014.
Are you ready?
Are you ready? Did you bring coffee and a good dose of energy? Let’s start! Your first point of action is to prepare your system for this course in Chapter 3.
Getting started
[THIS CHAPTER NEEDS WORK]
- introduction
- briefly touch on operating system
- split CoCalc vs standalone
- CoCalc: everything is installed
- standalone:
- focus on macOS
- what to install
- show how to navigate on macOS Terminal
[Some introductory text]
Your computer
Before getting started, we need to discuss your computer. Most programs made to execute genetic epidemiology studies are developed for the Unix environment, for example Linux and macOS. So, they may not work as intended in a Windows environment. Windows does allow users to install a linux subsystem within Windows 10+ and you can find the detail guide here.
However, I highly recommend one of two options.
- One, install a linux subsystem on your Windows computer (for example a virtual machine with Ubuntu could work).
- Two, switch to macOS in combination with homebrew. This will give you all the flexibility to use Unix-based programs for your genetic epidemiology work and at the same time you’ll keep the advantage of a powerful computer with a user-friendly interface.
I chose the latter.
For this practical every command is intended for Linux/macOS, in other words Unix-systems.
CoCalc vs. Standalone
For the purpose of this practical primer there are one of two steps you need to take to get started. When you are following the course, you will want to read the section CoCalc. When you want to use this book as a standalone, you should check out the instructions in section Standalone - this is probably also the section you want to follow for real-world cases.
But first, I’ll briefly provide some background on the various programs that are commonly used.
The programs we use
We’ll use a few programs throughout this practical. You’ll probably need these for your (future) genetic epidemiology work too (Table 3.1).
Table 3.1: Programs needed for genetic epidemiology.
Program | Link | Description |
|---|
PLINK | https://www.cog-genomics.org/plink2/ | PLINK is a free, open-source genetic analysis tool set, designed to perform a range of basic data parsing and quality control, as well as basic and large-scale analyses in a computationally efficient manner. |
R | https://cran.r-project.org/ | A program to perform statistical analysis and visualizations. |
RStudio | https://www.rstudio.com | A user-friendly R-wrap-around for code editing, debugging, analyses, and visualization. |
Homebrew | https://brew.sh | A great extension for Mac-users to install really useful programs that Apple didn't. |
RStudio
RStudio is a very user-friendly interface around R that makes your R-scripting-life a lot easier. You should get used to that. RStudio comes with R so you don’t have to worry about that.
PLINK
Right, onto PLINK.
All genetic analyses can be done in PLINK, even on your laptop, but with large datasets, for example UK Biobank size, it is better to switch to a high-performance computing cluster (HPC) like we have available at the Utrecht Science Park. The original PLINK v1.07 can be found here, but nowadays we are using a newer, faster version: PLINK v1.9 which can be found here. It still says ‘PLINK 1.90 beta’ (Figure 3.1), but you can consider this version stable and save to work with, but as you can see, some functions are not supported anymore.
Alternatives to PLINK
Nowadays, a lot of people also use programs like SNPTEST, BOLT-LMM, GCTA, or regenie as alternatives to execute GWAS. These programs were designed with specific use-cases in mind, for instance really large biobank data including hundreds of thousands individuals, better control for population stratification, the ability to estimate trait heritability or Fst, and so on.
Other programs
Mendelian randomization can be done either with the SMR or GSMR function from GCTA, or with R-packages, like TwoSampleMR.
CoCalc
[ TEXT NEEDS UPDATING]
Now, pay attention. If you came here through the course Genetic Epidemiology, you don’t have to do anything. All the data you need are already downloaded.
However, when you are using this book as a standalone, you’ll need to start by downloading the data you need for this practical to your Desktop.
For the course we set up a CoCalc Server and everything should be fine; we installed everything you need.
Standalone
So, you plan to use this book as ‘Standalone’ on a macOS environment. This means you’ll need to install a few things first.
The data you need
You’ll need to start by downloading the data you need for this practical to your Desktop.
Here’s the link to the data.
Link to Google Drive with data
Make sure you put the data in the ~/Desktop/practical/ folder.
The data are pretty large (approx. 15Gb), so this will take a minute or two depending on your internet connection. Time to stretch your legs or grab a coffee (data scientists don’t drink tea).
Terminal
For all the programs we use, except RStudio, you will need the Terminal. This comes with every major operating system; on Windows it is called ‘PowerShell’, but let’s not go there. And regardless, you will (have to start to) make your own scripts. The benefit of using scripts is that each step in your workflow is clearly stipulated and annotated, and it allows for greater reproducibility, easier troubleshooting, and scaling up to high-performance computer clusters.
Open the Terminal, it should be on the left in the toolbar as a little black computer-monitor-like icon. Mac users can type command + space and type terminal, a Terminal screen should open.
From now on we will use little code blocks like the example to indicate a code you should type/copy-paste and hit enter. If a code is followed by a comment, it is indicated by a # - you don’t need to copy-paste and execute this.
CODE BLOCK
CODE BLOCK # some comment here
Navigating the Terminal
You can navigate around the computer through the terminal by typing cd <path>; cd stands for “change directory” and <path> means “some_file_directory_you_want_to_go_to”.
This command will bring you to your home directory.
cd ~
This will bring you to the parent directory (up one level).
cd ../
This will bring you to the XXX directory.
cd XXX
Let’s navigate to the folder you just downloaded.
cd ~/Desktop/practical
Let’s check out what is inside the directory, by listing (ls) its contents.
This command shows files as list; the -l makes it a vertical list and adds more information, you can also remove it and simply type ls - go on, and try.
ls -l
This command shows files as list with human readable format.
ls -lh
Adding the flags -lh will get you the contents of a directory in a list (-l) and make the size ‘human-readable’ (-h).
Adding -t shows the files as list sorted by time edited.
ls -lt
Adding -S shows the files as list sorted by size.
ls -lS
You can also count the number of files. Just ‘pipe’ the result from ls to the next program wc (‘wordcount’) and list the number of lines, -l. In this case -l is a flag used by wc and it has a different meaning than it does for ls.
ls | wc -l
And if you want to know all the function of a program simply type the following.
man ls
This will take you to a manual of the program with an extensive description of each flag (Figure 3.2).
Installing the software
brew
Linux has a great package-manager that is lacking on macOS. You can install brew to compensate for this. This adds the ability to install almost any Linux-based program through the Terminal such as wget, llvm, etc.
Open Terminal and execute the following:
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
Check if everything is in order.
brew doctor
It shouldn’t report any errors.
PLINK
First, we’ll get PLINK. Navigate to the PLINK v1.9 website, which can be found here. Download the macOS (64-bit) version under ‘Stable (beta x.x, day month year)’.
Note: Apple produced Intel-based computers for a few years back, and most programs, packages, libraries and whatnot are designed for that. So, I highly recommend using software designed for that and activating Rosetta2 in your Terminal. Don’t know how to do that? Following these instructions.
Unzip the folder and put plink in the practical folder.
mv -v ~/Downloads/plink_mac_20231211/plink ~/Desktop/practical/plink
Installing R and RStudio
Let’s go ahead and use brew to install the R and RStudio software.
In Terminal execute the following and just follow the instructions.
brew install rstudio
brew install --cask r
Now close the terminal window - really make sure that the terminal-program has quit.
Open your fresh installation of RStudio by double clicking the icon. You should be seeing something like figure 3.3
In the top right, you see a little green-white plus-sign, click this and select ‘R Notebook’ (Figure 3.4).
You will create an untitled (Untitled1) R notebook: you can combine text descriptions, like you would in a lab-journal, with code-sections. Read what is in the notebook to get a grasp on that (Figure 3.5).
Right, you should be installing some packages. To do so, you can remove plot(cars) (or leave and create a new code-block as per instructions in the notebook), and copy paste the code below. Make sure to put in a code block like the example in which plot(cars) is in.
remotes::install_github(c("rstudio/rmarkdown"))
install.packages(c("formatR", "remotes",
"httr", "usethis",
"data.table", "devtools",
"dplyr", "tibble", "tidyverse",
"openxlsx",
"ggplot2",
"ggsci", "ggthemes",
"qqman", "CMplot", "plotly",
"openxlsx"))
devtools::install_github("kassambara/ggpubr")
devtools::install_github("oliviasabik/RACER")
remotes::install_github("MRCIEU/TwoSampleMR")
devtools::install_github("MRCIEU/MRInstruments")
if (!require("BiocManager", quietly = TRUE))
install.packages("BiocManager")
BiocManager::install("geneplotter")
You should load these packages too.
library(rmarkdown)
library(formatR)
library(openxlsx)
library(data.table)
library(tibble)
library(tidyverse)
library(dplyr)
library(plotly)
library(ggplot2)
library(devtools)
library(ggpubr)
library(ggsci)
library(ggthemes)
library(qqman)
library(CMplot)
library(RACER)
library(remotes)
library(TwoSampleMR)
library(MRInstruments)
library("geneplotter")
All in all this may take some time, good moment to relax, review your notes, stretch your legs, or take a coffee.
Are you ready?
Are you ready? Did you bring coffee and a good dose of energy? Let’s start!
Oh, one more thing: you can save your notebook, the one you just created, to keep all the R codes you are applying in the next chapters and add descriptions and notes. If you save this notebook you’ll notice that a html-file is created. This file is a legible webbrowser-friendly version of your work and contains the codes and the output (code messages, tables, and figures). And the nice thing is, that you can easily share it with others over email.
Ok. ’Nough said, let’s move on to cover some basics in Chapter ??.
Licenses and disclaimers
Copyright
This book and all its material (“content”) is protected by copyright under Dutch Copyright laws and is the property of the author or the party credited as the provider of the content. You may not copy, reproduce, distribute, publish, display, perform, modify, create derivative works, transmit, or in any way exploit any such content, nor may you distribute any part of this content over any network, including a local area network, sell or offer it for sale, or use such content to construct any kind of database. You may not alter or remove any copyright or other notice from copies of the content on this website. Copying or storing any content except as provided above is expressly prohibited without prior written permission of the author or the copyright holder identified in the individual content’s copyright notice. For permission to use this content, please contact the author.
Disclaimer
The content contained herein is provided only for educational and informational purposes or as required by Dutch law. The author attempted to ensure that content is accurate and obtained from reliable sources, but does not represent it to be error-free. The author may add, amend or repeal any text, procedure or regulation, and failure to timely post such changes to this book shall not be construed as a waiver of enforcement. The author does not warrant that any functions on this website or the contents and references herein will be uninterrupted, that defects will be corrected, or that this website or the contents and references will be free from viruses or other harmful components. Any links to third party information on the author’s website are provided as a courtesy and do not constitute an endorsement of those materials or the third party providing them.
Images and data used
I took the at-most care to use refer to the original works and data sources where needed. Likewise, all the images c.q. figures are either produced specifically for this book, or I took them from Unsplash to brighten up the book. If you feel I made a mistake and your work should be properly referenced, please don’t hesitate to contact me.
These are the images from Unsplash listed here in no particular order.
Colophon
The 2022 and 2024 editions of this book were produce in RStudio and with the bookdown package. Below a listing of installed programs and libraries, the operating system, and their specific versions.
## ─ Session info ───────────────────────────────────────────────────────────────
## setting value
## version R version 4.3.3 (2024-02-29)
## os macOS Sonoma 14.5
## system x86_64, darwin20
## ui X11
## language (EN)
## collate en_US.UTF-8
## ctype en_US.UTF-8
## tz America/New_York
## date 2024-04-04
## pandoc 3.1.1 @ /Applications/RStudio.app/Contents/Resources/app/quarto/bin/tools/ (via rmarkdown)
##
## ─ Packages ───────────────────────────────────────────────────────────────────
## package * version date (UTC) lib source
## askpass 1.2.0 2023-09-03 [2] CRAN (R 4.3.0)
## bookdown * 0.38.1 2024-03-26 [2] Github (rstudio/bookdown@50a1c1e)
## bslib 0.6.2 2024-03-22 [2] CRAN (R 4.3.2)
## cachem 1.0.8 2023-05-01 [2] CRAN (R 4.3.0)
## chromote 0.2.0 2024-02-12 [1] CRAN (R 4.3.2)
## cli 3.6.2 2023-12-11 [2] CRAN (R 4.3.0)
## colorspace 2.1-0 2023-01-23 [2] CRAN (R 4.3.0)
## crayon 1.5.2 2022-09-29 [2] CRAN (R 4.3.0)
## crul 1.4.0 2023-05-17 [2] CRAN (R 4.3.0)
## curl 5.2.1 2024-03-01 [2] CRAN (R 4.3.2)
## data.table 1.15.4 2024-03-30 [1] CRAN (R 4.3.2)
## digest 0.6.35 2024-03-11 [2] CRAN (R 4.3.2)
## evaluate 0.23 2023-11-01 [2] CRAN (R 4.3.0)
## fastmap 1.1.1 2023-02-24 [2] CRAN (R 4.3.0)
## flextable * 0.9.5 2024-03-06 [1] CRAN (R 4.3.2)
## fontBitstreamVera 0.1.1 2017-02-01 [2] CRAN (R 4.3.0)
## fontLiberation 0.1.0 2016-10-15 [2] CRAN (R 4.3.0)
## fontquiver 0.2.1 2017-02-01 [2] CRAN (R 4.3.0)
## formatR * 1.14 2023-01-17 [2] CRAN (R 4.3.0)
## gdtools 0.3.7 2024-03-05 [2] CRAN (R 4.3.2)
## gfonts 0.2.0 2023-01-08 [2] CRAN (R 4.3.0)
## glue 1.7.0 2024-01-09 [2] CRAN (R 4.3.0)
## htmltools 0.5.8 2024-03-25 [2] CRAN (R 4.3.2)
## httpcode 0.3.0 2020-04-10 [2] CRAN (R 4.3.0)
## httpuv 1.6.15 2024-03-26 [2] CRAN (R 4.3.2)
## jquerylib 0.1.4 2021-04-26 [2] CRAN (R 4.3.0)
## jsonlite 1.8.8 2023-12-04 [2] CRAN (R 4.3.0)
## kableExtra * 1.4.0 2024-01-24 [1] CRAN (R 4.3.2)
## knitr * 1.45 2023-10-30 [1] CRAN (R 4.3.0)
## later 1.3.2 2023-12-06 [2] CRAN (R 4.3.0)
## lifecycle 1.0.4 2023-11-07 [2] CRAN (R 4.3.0)
## magrittr 2.0.3 2022-03-30 [2] CRAN (R 4.3.0)
## mime 0.12 2021-09-28 [2] CRAN (R 4.3.0)
## munsell 0.5.1 2024-04-01 [1] CRAN (R 4.3.2)
## officer 0.6.5 2024-02-24 [2] CRAN (R 4.3.2)
## openssl 2.1.1 2023-09-25 [2] CRAN (R 4.3.0)
## processx 3.8.4 2024-03-16 [2] CRAN (R 4.3.2)
## promises 1.2.1 2023-08-10 [2] CRAN (R 4.3.0)
## ps 1.7.6 2024-01-18 [2] CRAN (R 4.3.0)
## R6 2.5.1 2021-08-19 [2] CRAN (R 4.3.0)
## ragg 1.3.0 2024-03-13 [2] CRAN (R 4.3.2)
## Rcpp 1.0.12 2024-01-09 [2] CRAN (R 4.3.0)
## rlang 1.1.3 2024-01-10 [2] CRAN (R 4.3.0)
## rmarkdown * 2.26.1 2024-03-26 [2] Github (rstudio/rmarkdown@ee69d59)
## rstudioapi 0.16.0 2024-03-24 [2] CRAN (R 4.3.2)
## sass 0.4.9 2024-03-15 [2] CRAN (R 4.3.2)
## scales 1.3.0 2023-11-28 [2] CRAN (R 4.3.0)
## sessioninfo 1.2.2 2021-12-06 [2] CRAN (R 4.3.0)
## shiny 1.8.1 2024-03-26 [2] CRAN (R 4.3.2)
## stringi 1.8.3 2023-12-11 [2] CRAN (R 4.3.0)
## stringr 1.5.1 2023-11-14 [2] CRAN (R 4.3.0)
## svglite 2.1.3 2023-12-08 [1] CRAN (R 4.3.0)
## systemfonts 1.0.6 2024-03-07 [2] CRAN (R 4.3.2)
## textshaping 0.3.7 2023-10-09 [2] CRAN (R 4.3.0)
## tinytex * 0.50 2024-03-16 [2] CRAN (R 4.3.2)
## uuid 1.2-0 2024-01-14 [2] CRAN (R 4.3.0)
## viridisLite 0.4.2 2023-05-02 [2] CRAN (R 4.3.0)
## webshot * 0.5.5 2023-06-26 [1] CRAN (R 4.3.0)
## webshot2 * 0.1.1 2023-08-11 [1] CRAN (R 4.3.0)
## websocket 1.4.1 2021-08-18 [1] CRAN (R 4.3.0)
## xfun 0.43 2024-03-25 [2] CRAN (R 4.3.2)
## xml2 1.3.6 2023-12-04 [2] CRAN (R 4.3.0)
## xtable 1.8-4 2019-04-21 [2] CRAN (R 4.3.0)
## yaml 2.3.8 2023-12-11 [2] CRAN (R 4.3.0)
## zip 2.3.1 2024-01-27 [2] CRAN (R 4.3.2)
##
## [1] /Users/slaan3/Library/R/x86_64/4.3/library
## [2] /Library/Frameworks/R.framework/Versions/4.3-x86_64/Resources/library
##
## ──────────────────────────────────────────────────────────────────────────────
References
LS0tIAp0aXRsZTogIkEgUHJhY3RpY2FsIFByaW1lciBpbiBIdW1hbiBDb21wbGV4IEdlbmV0aWNzIgpzdWJ0aXRsZTogIndpdGggYSB1c2UtY2FzZSBpbiBjYXJkaW92YXNjdWxhciBkaXNlYXNlIgphdXRob3I6ICJbZHIuIFNhbmRlciBXLiB2YW4gZGVyIExhYW5dKGh0dHBzOi8vdmFuZGVybGFhbmFuZC5zY2llbmNlKSBbIVtdKC4vaW1nL19sb2dvL3R3aXR0ZXJfY2lyY2xlX2JsdWUucG5nKXt3aWR0aD0yJX1dKGh0dHBzOi8vd3d3LnR3aXR0ZXIuY29tL3N3dmFuZGVybGFhbikgWyFbXSguL2ltZy9fbG9nby9lbWFpbF9jaXJjbGVfYmx1ZS5wbmcpe3dpZHRoPTIlfV0obWFpbHRvOnMudy52YW5kZXJsYWFuQGdtYWlsLmNvbSkiCmRhdGU6ICJWZXJzaW9uIDIuMC4yICgyMDI0LTA0LTA0KSIKZGVzY3JpcHRpb246ICJUaGlzIGlzIGEgcHJhY3RpY2FsIHByaW1lciBpbiBodW1hbiBjb21wbGV4IGdlbmV0aWNzIHdpdGggYSB1c2UtY2FzZSBpbiBjYXJkaW92YXNjdWxhciBkaXNlYXNlLiBUaGUgb3V0cHV0IGZvcm1hdCBmb3IgdGhpcyBwcmltZXIgaXMgYm9va2Rvd246OmdpdGJvb2suIgpkb2N1bWVudGNsYXNzOiBib29rCmdpdGh1Yi1yZXBvOiBzd3ZhbmRlcmxhYW4vQV9QcmFjdGljYWxfUHJpbWVyX2luX0h1bWFuX0NvbXBsZXhfR2VuZXRpY3MKbGluay1jaXRhdGlvbnM6IHllcwpiaWJsaW9ncmFwaHk6Ci0gYmlibGlvZ3JhcGh5L2Jvb2suYmliCi0gYmlibGlvZ3JhcGh5L3BhY2thZ2VzLmJpYgpiaWJsaW8tc3R5bGU6IGFwYWxpa2UKc2l0ZTogYm9va2Rvd246OmJvb2tkb3duX3NpdGUKYWx3YXlzX2FsbG93X2h0bWw6IHllcwojY292ZXItaW1hZ2U6ICJpbWFnZXMvY292ZXIucG5nIgojYXBwbGUtdG91Y2gtaWNvbjogInRvdWNoLWljb24ucG5nIgojYXBwbGUtdG91Y2gtaWNvbi1zaXplOiAxMjAKI2Zhdmljb246ICJmYXZpY29uLmljbyIKLS0tCgojIEFib3V0IHRoaXMgcHJpbWVyCgpFdmVyIHNpbmNlIHRoZSBmaXJzdCBnZW5vbWUtd2lkZSBhc3NvY2lhdGlvbiBzdHVkeSAoR1dBUykgb24gW2FnZS1yZWxhdGVkIG1hY3VsYXIgZGVnZW5lcmF0aW9uXShodHRwczovL2RvaS5vcmcvMTAuMTEyNi9zY2llbmNlLjExMDk1NTcpe3RhcmdldD0iX2JsYW5rIn0sIGFuZCB0aGUgcHJvbWlzZSBvZiBwZXJzb25hbGl6ZWQgbWVkaWNpbmUgaW4gdGhlIHdha2Ugb2YgdGhlIEh1bWFuIEdlbm9tZSBQcm9qZWN0LCBsYXJnZS1zY2FsZSBnZW5ldGljIGFzc29jaWF0aW9uIHN0dWRpZXMgaG9sZCBzaWduaWZpY2FudCBzd2F5IGluIGNvbnRlbXBvcmFyeSBoZWFsdGggcmVzZWFyY2ggYW5kIFtkcml2ZSBkcnVnLWRldmVsb3BtZW50IHBpcGVsaW5lc10oaHR0cDovL2R4LmRvaS5vcmcvMTAuMTAzOC9ucmQuMjAxNy4yNjIpe3RhcmdldD0iX2JsYW5rIn0uIEluIHRoZSBwYXN0IDIgZGVjYWRlcywgcmVzZWFyY2hlcnMgZGVsdmVkIGludG8gR1dBUywgYWltaW5nIHRvIHVudmVpbCBnZW5ldGljIHZhcmlhdGlvbnMgbGlua2VkIHRvIGJvdGggaHVtYW4gdHJhaXRzLCBzdWNoIGFzIHRoZSBjb2xvciBvZiB5b3VyIGV5ZXMsIGFuZCByYXJlIGFuZCBjb21tb24gY29tcGxleCBkaXNlYXNlcy4gVGhlc2UgZmluZGluZ3Mgc2VydmUgYXMgY3J1Y2lhbCBrZXlzIHRvIHVucmF2ZWwgdGhlIGludHJpY2F0ZSBtZWNoYW5pc21zIHVuZGVybHlpbmcgZGlzZWFzZXMsIHNoZWRkaW5nIGxpZ2h0IG9uIHdoZXRoZXIgdGhlIGNvcnJlbGF0aW9ucyBpZGVudGlmaWVkIGluIG9ic2VydmF0aW9uYWwgc3R1ZGllcyBiZXR3ZWVuIHJpc2sgZmFjdG9ycyBhbmQgZGlzZWFzZXMgYXJlIHRydWx5IGNhdXNhbC4gCgpUaGVzZSBzdHVkaWVzIGhhdmUgdXNoZXJlZCBpbiBhbiBleGNpdGluZyBlcmEgd2hlcmUgbWFueSByZXNlYXJjaGVycyB0aHJpdmUgb24gZGV2ZWxvcGluZyBuZXcgbWV0aG9kcyBhbmQgYmlvaW5mb3JtYXRpYyB0b29scyB0byBwYXJzZSBldmVyLWdyb3dpbmcgbGFyZ2UgZGF0YXNldHMgY29sbGVjdGVkIGxhcmdlIHBvcHVsYXRpb24tYmFzZWQgYmlvYmFua3MuIEhvd2V2ZXIsIHRoZSBhbmFseXNlcyBvZiB0aGVzZSBkYXRhIGFyZSBjaGFsbGVuZ2luZyBhbmQgaXQgY2FuIGJlIGRhdW50aW5nIHRvIHNlZSB0aGUgZm9yZXN0IGZvciB0cmVlIGFtb25nIHRoZSBtYW55IHRvb2xzIGFuZCB0aGVpciB2YXJpb3VzIGZ1bmN0aW9ucy4gRW50ZXIgX0EgUHJhY3RpY2FsIFByaW1lciBpbiBIdW1hbiBDb21wbGV4IEdlbmV0aWNzXy4gVGhpcyBbR2l0Qm9va10oaHR0cHM6Ly9janZhbmxpc3NhLmdpdGh1Yi5pby9naXRib29rLWRlbW8vKXt0YXJnZXQ9Il9ibGFuayJ9IHdhcyBvcmlnaW5hbGx5IHdyaXR0ZW4gYmFjayBpbiAyMDIyIGZvciB0aGUgKipHZW5ldGljIEVwaWRlbWlvbG9neSoqIGNvdXJzZSBvcmdhbml6ZWQgYnkgdGhlIFtNYXN0ZXIgRXBpZGVtaW9sb2d5XShodHRwczovL2VwaWRlbWlvbG9neS1lZHVjYXRpb24ubmwpe3RhcmdldD0iX2JsYW5rIn0gb2YgVXRyZWNodCBVbml2ZXJzaXR5LiBUaGlzIHByYWN0aWNhbCBndWlkZSB3aWxsIHRlYWNoIHlvdSBob3cgdG8gZGVzaWduIGEgR1dBUywgcGVyZm9ybSBxdWFsaXR5IGNvbnRyb2wgKFFDKSwgZXhlY3V0ZSB0aGUgYWN0dWFsIGFuYWx5c2VzLCBhbm5vdGF0ZSB0aGUgR1dBUyByZXN1bHRzLCBhbmQgcGVyZm9ybSBmdXJ0aGVyIGRvd25zdHJlYW0gcG9zdC1HV0FTIGFuYWx5c2VzLiBUaHJvdWdob3V0IHRoZSBib29rIHlvdSdsbCB3b3JrIHdpdGggJ2R1bW15JywgdGhhdCBpcyBmYWtlLCBkYXRhLCBidXQgaW4gdGhlIGVuZCwgd2Ugd2lsbCB1c2UgcmVhbC13b3JsZCBkYXRhIGZyb20gdGhlIGZpcnN0IHJlbGVhc2Ugb2YgdGhlIFsqV2VsY29tZSBUcnVzdCBDYXNlLUNvbnRyb2wgQ29uc29ydGl1bSAoV1RDQ0MpKl0oaHR0cHM6Ly93d3cud3RjY2Mub3JnLnVrL2NjYzEvb3ZlcnZpZXcuaHRtbCl7dGFyZ2V0PSJfYmxhbmsifSBmb2N1c2luZyBvbiBjb3JvbmFyeSBhcnRlcnkgZGlzZWFzZSAoQ0FEKS4gCgpBIG1ham9yIGNvbXBvbmVudCBvZiBtb2Rlcm4tZGF5IEdXQVMgaXMgW2dlbmV0aWMgaW1wdXRhdGlvbl0oaHR0cHM6Ly93d3cubmF0dXJlLmNvbS9hcnRpY2xlcy9ucmcyNzk2KXt0YXJnZXQ9Il9ibGFuayJ9LCBidXQgZm9yIHByYWN0aWNhbCByZWFzb25zIGl0IGlzIG5vdCBwYXJ0IG9mIHRoaXMgYm9vay4gSG93ZXZlciwgSSB3aWxsIHByb3ZpZGUgc29tZSBwb2ludGVycyBhcyB0byBob3cgdG8gZ28gYWJvdXQgZG8gdGhpcyB3aXRoIG1pbmltYWwgY29kaW5nIG9yIHNjcmlwdGluZyBleHBlcmllbmNlLiBMaWtld2lzZSwgdGhlIGNvdXJzZXMgZG9lcyBub3QgY292ZXIgdGhlIGFzcGVjdHMgb2YgbWV0YS1hbmFseXNlcyBvZiBHV0FTLCBidXQgc29tZSBleGNlbGxlbnQgcmVzb3VyY2VzIGV4aXN0IHRvIHdoaWNoIEkgd2lsbCBkaXJlY3QuIEFzIHRoaXMgcHJhY3RpY2FsIHByaW1lciBldm9sdmVzLCB0aGVzZSBhbmQgb3RoZXIgdG9waWNzIG1heSBmaW5kIHRoZWlyIHBsYWNlIGluIHRoaXMgYm9vay4gCkkgc2hvdWxkIGFsc28gcG9pbnQgb3V0IHRoYXQgZW1waGFzaXMgb2YgdGhpcyBib29rIGlzIG9uIGl0IGJlaW5nIGEgX3ByYWN0aWNhbCBwcmltZXJfLiBJdCBpcyBpbnRlbmRlZCB0byBwcm92aWRlIHNvbWUgcHJhY3RpY2FsIGd1aWRhbmNlIHRvIGRvaW5nIEdXQVMsIGFuZCB3aGlsZSB0aGVvcnkgaXMgaW1wb3J0YW50LCBJIHdpbGwgbm90IGNvdmVyIHRoaXMuIEFnYWluLCBzb21lIHZlcnkgdXNlZnVsIGFuZCBleGNlbGxlbnQgd29yayBleGlzdHMgdG8gd2hpY2ggSSB3aWxsIHBvaW50IHlvdSwgYnV0IEkgcmVhbGx5IHdhbnQgeW91IHRvIGxlYXJuIC0gYW5kIHVuZGVyc3RhbmQgdGhlIHRoZW9yeSAtIGJ5IF9kb2luZ18uIAoKU28sIGFsdGhvdWdoIG9yaWdpbmFsbHkgY3JhZnRlZCBhcyBhIGNvbXBhbmlvbiBmb3IgdGhlIGNvdXJzZSwgdGhpcyBwcmFjdGljYWwgZ3VpZGUgc3RhbmRzIG9uIGl0cyBvd24gYXMgYSBjb21wcmVoZW5zaXZlIHJlc291cmNlIGZvciBkaXZpbmcgaW50byBhbGwgZmFjZXRzIG9mIGRvaW5nIGEgR1dBUyDigJQgc2F2ZSBmb3IgZXhwZXJpbWVudGFsIGZvbGxvdy11cCwgb2YgY291cnNlIPCfmIkuCgpJIGNhbiBpbWFnaW5lIHRoaXMgc2VlbXMgb3ZlcndoZWxtaW5nLCBidXQgdHJ1c3QgbWUsIHlvdSdsbCBiZSBva2F5LiBKdXN0IGZvbGxvdyB0aGlzIHByYWN0aWNhbC4gWW91J2xsIGxlYXJuIGJ5IGRvaW5nIGFuZCBhdCB0aGUgZW5kIG9mIHRoZSBkYXksIHlvdSBjYW4gZXhlY3V0ZSBhIEdXQVMgaW5kZXBlbmRlbnRseS4KCioqUmVhZHkgdG8gc3RhcnQ/KioKCjwhLS0gWW91ciBmaXJzdCBwb2ludCBvZiBhY3Rpb24gaXMgdG8gcHJlcGFyZSB5b3VyIHN5c3RlbSBmb3IgdGhpcyBjb3Vyc2UgaW4gQ2hhcHRlciBcQHJlZihzb21lYmFja2dyb3VuZHJlYWRpbmcpLiAtLT4KCjxzY3JpcHQ+CnRpdGxlPWRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdoZWFkZXInKTsKdGl0bGUuaW5uZXJIVE1MID0gJzxpbWcgc3JjPSJpbWcvX2hlYWRlcnMvYmFubmVyX21hbl9zdGFuZGluZ19kbmEucG5nIiBhbHQ9IkEgUHJhY3RpY2FsIFByaW1lciBpbiBIdW1hbiBDb21wbGV4IEdlbmV0aWNzIj4nICsgdGl0bGUuaW5uZXJIVE1MCjwvc2NyaXB0PgoKPCEtLWNoYXB0ZXI6ZW5kOmluZGV4LlJtZC0tPgoKIyBTb21lIGJhY2tncm91bmQgcmVhZGluZyAgeyNzb21lYmFja2dyb3VuZHJlYWRpbmd9CjwhLS0gIVtdKC4vaW1nL19oZWFkZXJzL3BhcGVyc19vbl93YWxsLnBuZyl7d2lkdGg9MTAwJX0gLS0+CgoKCgoKU3RhbmRpbmcgb24gdGhlIHNob3VsZGVycyBvZiBnaWFudHMsIHRoYXQncyB3aGF0IHRoaXMgYm9vayBhbmQgSSBkby4gSSB3YW50IHRvIGFja25vd2xlZGdlIHNvbWUgZ3JlYXQgd29yayB0aGF0IGhhcyBoZWxwZWQgbWUgdHJlbWVuZG91c2x5IGFuZCwgcmVhbGx5LCB0aGlzIGJvb2sgd291bGRuJ3QgZXhpc3Qgd2l0aG91dCB0aGlzIGF3ZXNvbWUgd29yay4gU28sIEkgZG8gd2FudCB0byBnaXZlIHlvdSBzb21lIGJhY2tncm91bmQgcmVhZGluZy4gSXMgaXQgYSBwcmVyZXF1aXNpdGU/IE5vLCBub3QgcmVhbGx5LiBGb3Igc3RhcnRlcnMsIHRoZSBjb3Vyc2UgY292ZXJzIG1vc3QgYW5kIHlvdSdsbCBsZWFybiBhcyB5b3UgZ28uIEFuZCBpZiB5b3UgZGlkbid0IGNvbWUgaGVyZSB0aHJvdWdoIHRoZSBjb3Vyc2UsIHlvdSdsbCBiZSBmaW5lIGp1c3QgdGhlIHNhbWUuIFRoYXQgc2FpZCwgaXQncyBhIGFsd2F5cyBnb29kIGlkZWEgdG8gZ2V0IGZhbWlsaWFyIHdpdGggdGhlc2Ugd29ya3MgYXMgeW91IG1vdmUgZm9yd2FyZCBvbiB5b3VyIHBhdGggdG93YXJkcyB5b3VyIGZpcnN0IEdXQVMgLSBpbiBmYWN0LCBJIGhhZCB0aGVzZSBwcmludGVkIG91dCB3aXRoIG1hcmtpbmdzIGFuZCB3cml0aW5ncyBhbGwgb3ZlciB0aGVtIGFzIEkgZXhlY3V0ZWQgbXkgZmlyc3QgR1dBUywgYW5kIHRoZXkndmUgYmVlbiBncmVhdCBhcyBhIHJlZmVyZW5jZSBtYW55IHRpbWVzIGFmdGVyLiAKCkxhcmdlIHBhcnRzIG9mIHRoaXMgd29yayBhcmUgYmFzZWQgb24gZm91ciBhd2Vzb21lIE5hdHVyZSBQcm90b2NvbHMgZnJvbSB0aGUgW1pvbmRlcnZhbiBncm91cF0oaHR0cHM6Ly93d3cud2VsbC5veC5hYy51ay9yZXNlYXJjaC9yZXNlYXJjaC1ncm91cHMvem9uZGVydmFuLWdyb3VwKXt0YXJnZXQ9Il9ibGFuayJ9IGF0IHRoZSBXZWxsY29tZSBDZW50ZXIgSHVtYW4gR2VuZXRpY3MuCgoxLiBbWm9uZGVydmFuIEtUIF9ldCBhbC5fICpEZXNpZ25pbmcgY2FuZGlkYXRlIGdlbmUgYW5kIGdlbm9tZS13aWRlIGNhc2UtY29udHJvbCBhc3NvY2lhdGlvbiBzdHVkaWVzLiogTmF0IFByb3RvYyAyMDA3Ll0oaHR0cHM6Ly93d3cubmNiaS5ubG0ubmloLmdvdi9wdWJtZWQvMTc5NDc5OTEpe3RhcmdldD0iX2JsYW5rIn0KMi4gW1BldHRlcnNzb24gRkggX2V0IGFsLl8gKk1hcmtlciBzZWxlY3Rpb24gZm9yIGdlbmV0aWMgY2FzZS1jb250cm9sIGFzc29jaWF0aW9uIHN0dWRpZXMuKiBOYXQgUHJvdG9jIDIwMDkuXShodHRwczovL3d3dy5uY2JpLm5sbS5uaWguZ292L3B1Ym1lZC8xOTM5MDUzMCl7dGFyZ2V0PSJfYmxhbmsifQozLiBbQW5kZXJzb24gQ0EgX2V0IGFsLl8gKkRhdGEgUUMgaW4gZ2VuZXRpYyBjYXNlLWNvbnRyb2wgYXNzb2NpYXRpb24gc3R1ZGllcy4qIE5hdCBQcm90b2MgMjAxMC5dKGh0dHBzOi8vd3d3Lm5jYmkubmxtLm5paC5nb3YvcHVibWVkLzIxMDg1MTIyKXt0YXJnZXQ9Il9ibGFuayJ9CjQuIFtDbGFya2UgR00gX2V0IGFsLl8gKkJhc2ljIHN0YXRpc3RpY2FsIGFuYWx5c2lzIGluIGdlbmV0aWMgY2FzZS1jb250cm9sIHN0dWRpZXMuKiBOYXQgUHJvdG9jIDIwMTEuXShodHRwczovL3d3dy5uY2JpLm5sbS5uaWguZ292L3B1Ym1lZC8yMTI5MzQ1Myl7dGFyZ2V0PSJfYmxhbmsifQoKQW4gdXBkYXRlIG9uIHRoZSBjb21tdW5pdHkgc3RhbmRhcmRzIG9mIFFDIGZvciBHV0FTIGNhbiBiZSBmb3VuZCBoZXJlOgoKMS4gW0xhdXJpZSBDQyBfZXQgYWwuXyAqUXVhbGl0eSBjb250cm9sIGFuZCBxdWFsaXR5IGFzc3VyYW5jZSBpbiBnZW5vdHlwaWMgZGF0YSBmb3IgZ2Vub21lLXdpZGUgYXNzb2NpYXRpb24gc3R1ZGllcy4qIEdlbmV0IEVwaWRlbWlvbCAyMDEwLl0oaHR0cHM6Ly93d3cubmNiaS5ubG0ubmloLmdvdi9wdWJtZWQvMjA3MTgwNDUpe3RhcmdldD0iX2JsYW5rIn0KCldpdGggcmVzcGVjdCB0byBpbXB1dGF0aW9uIGFuZCBtZXRhLWFuYWx5c2VzIG9mIEdXQVMgeW91IHNob3VsZCBhbHNvIGdldCBmYW1pbGlhciB3aXRoIHRoZSBmb2xsb3dpbmcgdHdvIHdvcmtzOgoKMS4gW01hcmNoaW5pLCBKLiBhbmQgSG93aWUsIEIuICpHZW5vdHlwZSBpbXB1dGF0aW9uIGZvciBnZW5vbWUtd2lkZSBhc3NvY2lhdGlvbiBzdHVkaWVzLiogTmF0IFJldiBHZW5ldCAyMDEwXShodHRwczovL2RvaS5vcmcvMTAuMTAzOC9ucmcyNzk2KXt0YXJnZXQ9Il9ibGFuayJ9CjIuIFtkZSBCYWtrZXIgUElXIF9ldCBhbC5fICpQcmFjdGljYWwgYXNwZWN0cyBvZiBpbXB1dGF0aW9uLWRyaXZlbiBtZXRhLWFuYWx5c2lzIG9mIGdlbm9tZS13aWRlIGFzc29jaWF0aW9uIHN0dWRpZXMuKiBIdW0gTW9sIEdlbmV0IDIwMDguXShodHRwczovL3d3dy5uY2JpLm5sbS5uaWguZ292L3B1Ym1lZC8xODg1MjIwMCl7dGFyZ2V0PSJfYmxhbmsifQozLiBbV2lua2xlciBUVyBfZXQgYWwuXyAqUXVhbGl0eSBjb250cm9sIGFuZCBjb25kdWN0IG9mIGdlbm9tZS13aWRlIGFzc29jaWF0aW9uIG1ldGEtYW5hbHlzZXMuKiBOYXQgUHJvdG9jIDIwMTQuXShodHRwczovL3d3dy5uY2JpLm5sbS5uaWguZ292L3B1Ym1lZC8yNDc2Mjc4Nil7dGFyZ2V0PSJfYmxhbmsifQoKCioqQXJlIHlvdSByZWFkeT8qKgoKQXJlIHlvdSByZWFkeT8gRGlkIHlvdSBicmluZyBjb2ZmZWUgYW5kIGEgZ29vZCBkb3NlIG9mIGVuZXJneT8gTGV0J3Mgc3RhcnQhIFlvdXIgZmlyc3QgcG9pbnQgb2YgYWN0aW9uIGlzIHRvIHByZXBhcmUgeW91ciBzeXN0ZW0gZm9yIHRoaXMgY291cnNlIGluIENoYXB0ZXIgXEByZWYoZ2V0dGluZy1zdGFydGVkKS4KCjwhLS0gYGBge2pzLCBlY2hvID0gRkFMU0V9IC0tPgo8IS0tIHRpdGxlPWRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdoZWFkZXInKTsgLS0+CjwhLS0gdGl0bGUuaW5uZXJIVE1MID0gJzxpbWcgc3JjPSJpbWcvX2hlYWRlcnMvcGFwZXJzX29uX3dhbGwucG5nIiBhbHQ9IlNvbWUgYmFja2dyb3VuZCByZWFkaW5nIj4nICsgdGl0bGUuaW5uZXJIVE1MIC0tPgo8IS0tIGBgYCAtLT4KCjwhLS1jaGFwdGVyOmVuZDowMl8xX3NvbWViYWNrZ3JvdW5kcmVhZGluZy5SbWQtLT4KCiMgR2V0dGluZyBzdGFydGVkIHsjZ2V0dGluZy1zdGFydGVkfQo8IS0tICFbXSguL2ltZy9faGVhZGVycy93b21lbl9iZWhpbmRfbWFjYm9vay5wbmcpe3dpZHRoPTEwMCV9IC0tPgoKCgoKCgo+IFtUSElTIENIQVBURVIgTkVFRFMgV09SS10KPgo+IC0gaW50cm9kdWN0aW9uCj4gLSBicmllZmx5IHRvdWNoIG9uIG9wZXJhdGluZyBzeXN0ZW0KPiAtIHNwbGl0IENvQ2FsYyB2cyBzdGFuZGFsb25lCj4gICAtIENvQ2FsYzogZXZlcnl0aGluZyBpcyBpbnN0YWxsZWQKPiAgIC0gc3RhbmRhbG9uZTogCj4gICAgIC0gZm9jdXMgb24gbWFjT1MKPiAgICAgLSB3aGF0IHRvIGluc3RhbGwKPiAgICAgLSBzaG93IGhvdyB0byBuYXZpZ2F0ZSBvbiBtYWNPUyBUZXJtaW5hbAo+IFtTb21lIGludHJvZHVjdG9yeSB0ZXh0XQoKIyMgWW91ciBjb21wdXRlcgoKQmVmb3JlIGdldHRpbmcgc3RhcnRlZCwgd2UgbmVlZCB0byBkaXNjdXNzIHlvdXIgY29tcHV0ZXIuIE1vc3QgcHJvZ3JhbXMgbWFkZSB0byBleGVjdXRlIGdlbmV0aWMgZXBpZGVtaW9sb2d5IHN0dWRpZXMgYXJlIGRldmVsb3BlZCBmb3IgdGhlIFVuaXggZW52aXJvbm1lbnQsIGZvciBleGFtcGxlIExpbnV4IGFuZCBtYWNPUy4gU28sIHRoZXkgbWF5IG5vdCB3b3JrIGFzIGludGVuZGVkIGluIGEgV2luZG93cyBlbnZpcm9ubWVudC4gV2luZG93cyBkb2VzIGFsbG93IHVzZXJzIHRvIGluc3RhbGwgYSBsaW51eCBzdWJzeXN0ZW0gd2l0aGluIFdpbmRvd3MgMTArIGFuZCB5b3UgY2FuIGZpbmQgdGhlIGRldGFpbCBbZ3VpZGVdKGh0dHBzOi8vZG9jcy5taWNyb3NvZnQuY29tL2VuLXVzL3dpbmRvd3Mvd3NsL2Fib3V0KXt0YXJnZXQ9Il9ibGFuayJ9IGhlcmUuICAKCkhvd2V2ZXIsIEkgaGlnaGx5IHJlY29tbWVuZCBvbmUgb2YgdHdvIG9wdGlvbnMuIAoKLSBPbmUsIGluc3RhbGwgYSBsaW51eCBzdWJzeXN0ZW0gb24geW91ciBXaW5kb3dzIGNvbXB1dGVyIChmb3IgZXhhbXBsZSBbYSB2aXJ0dWFsIG1hY2hpbmUgd2l0aCBVYnVudHUgY291bGQgd29ya10oaHR0cHM6Ly9ibG9nLnN0b3JhZ2VjcmFmdC5jb20vdGhlLWRlYWQtc2ltcGxlLWd1aWRlLXRvLWluc3RhbGxpbmctYS1saW51eC12aXJ0dWFsLW1hY2hpbmUtb24td2luZG93cy8pe3RhcmdldD0iX2JsYW5rIn0pLiAKLSBUd28sIHN3aXRjaCB0byBtYWNPUyBpbiBjb21iaW5hdGlvbiB3aXRoIFtob21lYnJld10oaHR0cHM6Ly9icmV3LnNoKXt0YXJnZXQ9Il9ibGFuayJ9LiBUaGlzIHdpbGwgZ2l2ZSB5b3UgYWxsIHRoZSBmbGV4aWJpbGl0eSB0byB1c2UgVW5peC1iYXNlZCBwcm9ncmFtcyBmb3IgeW91ciBnZW5ldGljIGVwaWRlbWlvbG9neSB3b3JrIGFuZCBhdCB0aGUgc2FtZSB0aW1lIHlvdSdsbCBrZWVwIHRoZSBhZHZhbnRhZ2Ugb2YgYSBwb3dlcmZ1bCBjb21wdXRlciB3aXRoIGEgdXNlci1mcmllbmRseSBpbnRlcmZhY2UuCgpJIGNob3NlIHRoZSBsYXR0ZXIuIAoKPiBGb3IgdGhpcyBwcmFjdGljYWwgZXZlcnkgY29tbWFuZCBpcyBpbnRlbmRlZCBmb3IgTGludXgvbWFjT1MsIGluIG90aGVyIHdvcmRzIFVuaXgtc3lzdGVtcy4KCiMjIENvQ2FsYyB2cy4gU3RhbmRhbG9uZQoKRm9yIHRoZSBwdXJwb3NlIG9mIHRoaXMgcHJhY3RpY2FsIHByaW1lciB0aGVyZSBhcmUgb25lIG9mIHR3byBzdGVwcyB5b3UgbmVlZCB0byB0YWtlIHRvIGdldCBzdGFydGVkLiBXaGVuIHlvdSBhcmUgZm9sbG93aW5nIHRoZSBjb3Vyc2UsIHlvdSB3aWxsIHdhbnQgdG8gcmVhZCB0aGUgc2VjdGlvbiAqKkNvQ2FsYyoqLiBXaGVuIHlvdSB3YW50IHRvIHVzZSB0aGlzIGJvb2sgYXMgYSBzdGFuZGFsb25lLCB5b3Ugc2hvdWxkIGNoZWNrIG91dCB0aGUgaW5zdHJ1Y3Rpb25zIGluIHNlY3Rpb24gKipTdGFuZGFsb25lKiogLSB0aGlzIGlzIHByb2JhYmx5IGFsc28gdGhlIHNlY3Rpb24geW91IHdhbnQgdG8gZm9sbG93IGZvciByZWFsLXdvcmxkIGNhc2VzLiAKCkJ1dCBmaXJzdCwgSSdsbCBicmllZmx5IHByb3ZpZGUgc29tZSBiYWNrZ3JvdW5kIG9uIHRoZSB2YXJpb3VzIHByb2dyYW1zIHRoYXQgYXJlIGNvbW1vbmx5IHVzZWQuCgojIyBUaGUgcHJvZ3JhbXMgd2UgdXNlCgpXZSdsbCB1c2UgYSBmZXcgcHJvZ3JhbXMgdGhyb3VnaG91dCB0aGlzIHByYWN0aWNhbC4gWW91J2xsIHByb2JhYmx5IG5lZWQgdGhlc2UgZm9yIHlvdXIgKGZ1dHVyZSkgZ2VuZXRpYyBlcGlkZW1pb2xvZ3kgd29yayB0b28gKFRhYmxlIFxAcmVmKHRhYjpwcm9ncmFtcykpLgoKCgoKCmBgYHs9aHRtbH0KPGRpdiBjbGFzcz0idGFid2lkIj48c3R5bGU+LmNsLTI5ZGEwMDI4e30uY2wtMjlkMzQzOGN7Zm9udC1mYW1pbHk6J0hlbHZldGljYSc7Zm9udC1zaXplOjExcHQ7Zm9udC13ZWlnaHQ6bm9ybWFsO2ZvbnQtc3R5bGU6bm9ybWFsO3RleHQtZGVjb3JhdGlvbjpub25lO2NvbG9yOnJnYmEoMCwgMCwgMCwgMS4wMCk7YmFja2dyb3VuZC1jb2xvcjp0cmFuc3BhcmVudDt9LmNsLTI5ZDY1NjEye21hcmdpbjowO3RleHQtYWxpZ246bGVmdDtib3JkZXItYm90dG9tOiAwIHNvbGlkIHJnYmEoMCwgMCwgMCwgMS4wMCk7Ym9yZGVyLXRvcDogMCBzb2xpZCByZ2JhKDAsIDAsIDAsIDEuMDApO2JvcmRlci1sZWZ0OiAwIHNvbGlkIHJnYmEoMCwgMCwgMCwgMS4wMCk7Ym9yZGVyLXJpZ2h0OiAwIHNvbGlkIHJnYmEoMCwgMCwgMCwgMS4wMCk7cGFkZGluZy1ib3R0b206NXB0O3BhZGRpbmctdG9wOjVwdDtwYWRkaW5nLWxlZnQ6NXB0O3BhZGRpbmctcmlnaHQ6NXB0O2xpbmUtaGVpZ2h0OiAxO2JhY2tncm91bmQtY29sb3I6dHJhbnNwYXJlbnQ7fS5jbC0yOWQ2NjkyMnt3aWR0aDowLjkyNGluO2JhY2tncm91bmQtY29sb3I6dHJhbnNwYXJlbnQ7dmVydGljYWwtYWxpZ246IG1pZGRsZTtib3JkZXItYm90dG9tOiAxLjVwdCBzb2xpZCByZ2JhKDEwMiwgMTAyLCAxMDIsIDEuMDApO2JvcmRlci10b3A6IDEuNXB0IHNvbGlkIHJnYmEoMTAyLCAxMDIsIDEwMiwgMS4wMCk7Ym9yZGVyLWxlZnQ6IDAgc29saWQgcmdiYSgwLCAwLCAwLCAxLjAwKTtib3JkZXItcmlnaHQ6IDAgc29saWQgcmdiYSgwLCAwLCAwLCAxLjAwKTttYXJnaW4tYm90dG9tOjA7bWFyZ2luLXRvcDowO21hcmdpbi1sZWZ0OjA7bWFyZ2luLXJpZ2h0OjA7fS5jbC0yOWQ2NjkyY3t3aWR0aDoyLjcxNmluO2JhY2tncm91bmQtY29sb3I6dHJhbnNwYXJlbnQ7dmVydGljYWwtYWxpZ246IG1pZGRsZTtib3JkZXItYm90dG9tOiAxLjVwdCBzb2xpZCByZ2JhKDEwMiwgMTAyLCAxMDIsIDEuMDApO2JvcmRlci10b3A6IDEuNXB0IHNvbGlkIHJnYmEoMTAyLCAxMDIsIDEwMiwgMS4wMCk7Ym9yZGVyLWxlZnQ6IDAgc29saWQgcmdiYSgwLCAwLCAwLCAxLjAwKTtib3JkZXItcmlnaHQ6IDAgc29saWQgcmdiYSgwLCAwLCAwLCAxLjAwKTttYXJnaW4tYm90dG9tOjA7bWFyZ2luLXRvcDowO21hcmdpbi1sZWZ0OjA7bWFyZ2luLXJpZ2h0OjA7fS5jbC0yOWQ2NjkyZHt3aWR0aDoxNC4wMDJpbjtiYWNrZ3JvdW5kLWNvbG9yOnRyYW5zcGFyZW50O3ZlcnRpY2FsLWFsaWduOiBtaWRkbGU7Ym9yZGVyLWJvdHRvbTogMS41cHQgc29saWQgcmdiYSgxMDIsIDEwMiwgMTAyLCAxLjAwKTtib3JkZXItdG9wOiAxLjVwdCBzb2xpZCByZ2JhKDEwMiwgMTAyLCAxMDIsIDEuMDApO2JvcmRlci1sZWZ0OiAwIHNvbGlkIHJnYmEoMCwgMCwgMCwgMS4wMCk7Ym9yZGVyLXJpZ2h0OiAwIHNvbGlkIHJnYmEoMCwgMCwgMCwgMS4wMCk7bWFyZ2luLWJvdHRvbTowO21hcmdpbi10b3A6MDttYXJnaW4tbGVmdDowO21hcmdpbi1yaWdodDowO30uY2wtMjlkNjY5MzZ7d2lkdGg6MC45MjRpbjtiYWNrZ3JvdW5kLWNvbG9yOnRyYW5zcGFyZW50O3ZlcnRpY2FsLWFsaWduOiBtaWRkbGU7Ym9yZGVyLWJvdHRvbTogMCBzb2xpZCByZ2JhKDAsIDAsIDAsIDEuMDApO2JvcmRlci10b3A6IDAgc29saWQgcmdiYSgwLCAwLCAwLCAxLjAwKTtib3JkZXItbGVmdDogMCBzb2xpZCByZ2JhKDAsIDAsIDAsIDEuMDApO2JvcmRlci1yaWdodDogMCBzb2xpZCByZ2JhKDAsIDAsIDAsIDEuMDApO21hcmdpbi1ib3R0b206MDttYXJnaW4tdG9wOjA7bWFyZ2luLWxlZnQ6MDttYXJnaW4tcmlnaHQ6MDt9LmNsLTI5ZDY2OTM3e3dpZHRoOjIuNzE2aW47YmFja2dyb3VuZC1jb2xvcjp0cmFuc3BhcmVudDt2ZXJ0aWNhbC1hbGlnbjogbWlkZGxlO2JvcmRlci1ib3R0b206IDAgc29saWQgcmdiYSgwLCAwLCAwLCAxLjAwKTtib3JkZXItdG9wOiAwIHNvbGlkIHJnYmEoMCwgMCwgMCwgMS4wMCk7Ym9yZGVyLWxlZnQ6IDAgc29saWQgcmdiYSgwLCAwLCAwLCAxLjAwKTtib3JkZXItcmlnaHQ6IDAgc29saWQgcmdiYSgwLCAwLCAwLCAxLjAwKTttYXJnaW4tYm90dG9tOjA7bWFyZ2luLXRvcDowO21hcmdpbi1sZWZ0OjA7bWFyZ2luLXJpZ2h0OjA7fS5jbC0yOWQ2NjkzOHt3aWR0aDoxNC4wMDJpbjtiYWNrZ3JvdW5kLWNvbG9yOnRyYW5zcGFyZW50O3ZlcnRpY2FsLWFsaWduOiBtaWRkbGU7Ym9yZGVyLWJvdHRvbTogMCBzb2xpZCByZ2JhKDAsIDAsIDAsIDEuMDApO2JvcmRlci10b3A6IDAgc29saWQgcmdiYSgwLCAwLCAwLCAxLjAwKTtib3JkZXItbGVmdDogMCBzb2xpZCByZ2JhKDAsIDAsIDAsIDEuMDApO2JvcmRlci1yaWdodDogMCBzb2xpZCByZ2JhKDAsIDAsIDAsIDEuMDApO21hcmdpbi1ib3R0b206MDttYXJnaW4tdG9wOjA7bWFyZ2luLWxlZnQ6MDttYXJnaW4tcmlnaHQ6MDt9LmNsLTI5ZDY2OTQwe3dpZHRoOjAuOTI0aW47YmFja2dyb3VuZC1jb2xvcjp0cmFuc3BhcmVudDt2ZXJ0aWNhbC1hbGlnbjogbWlkZGxlO2JvcmRlci1ib3R0b206IDEuNXB0IHNvbGlkIHJnYmEoMTAyLCAxMDIsIDEwMiwgMS4wMCk7Ym9yZGVyLXRvcDogMCBzb2xpZCByZ2JhKDAsIDAsIDAsIDEuMDApO2JvcmRlci1sZWZ0OiAwIHNvbGlkIHJnYmEoMCwgMCwgMCwgMS4wMCk7Ym9yZGVyLXJpZ2h0OiAwIHNvbGlkIHJnYmEoMCwgMCwgMCwgMS4wMCk7bWFyZ2luLWJvdHRvbTowO21hcmdpbi10b3A6MDttYXJnaW4tbGVmdDowO21hcmdpbi1yaWdodDowO30uY2wtMjlkNjY5NDF7d2lkdGg6Mi43MTZpbjtiYWNrZ3JvdW5kLWNvbG9yOnRyYW5zcGFyZW50O3ZlcnRpY2FsLWFsaWduOiBtaWRkbGU7Ym9yZGVyLWJvdHRvbTogMS41cHQgc29saWQgcmdiYSgxMDIsIDEwMiwgMTAyLCAxLjAwKTtib3JkZXItdG9wOiAwIHNvbGlkIHJnYmEoMCwgMCwgMCwgMS4wMCk7Ym9yZGVyLWxlZnQ6IDAgc29saWQgcmdiYSgwLCAwLCAwLCAxLjAwKTtib3JkZXItcmlnaHQ6IDAgc29saWQgcmdiYSgwLCAwLCAwLCAxLjAwKTttYXJnaW4tYm90dG9tOjA7bWFyZ2luLXRvcDowO21hcmdpbi1sZWZ0OjA7bWFyZ2luLXJpZ2h0OjA7fS5jbC0yOWQ2Njk0Mnt3aWR0aDoxNC4wMDJpbjtiYWNrZ3JvdW5kLWNvbG9yOnRyYW5zcGFyZW50O3ZlcnRpY2FsLWFsaWduOiBtaWRkbGU7Ym9yZGVyLWJvdHRvbTogMS41cHQgc29saWQgcmdiYSgxMDIsIDEwMiwgMTAyLCAxLjAwKTtib3JkZXItdG9wOiAwIHNvbGlkIHJnYmEoMCwgMCwgMCwgMS4wMCk7Ym9yZGVyLWxlZnQ6IDAgc29saWQgcmdiYSgwLCAwLCAwLCAxLjAwKTtib3JkZXItcmlnaHQ6IDAgc29saWQgcmdiYSgwLCAwLCAwLCAxLjAwKTttYXJnaW4tYm90dG9tOjA7bWFyZ2luLXRvcDowO21hcmdpbi1sZWZ0OjA7bWFyZ2luLXJpZ2h0OjA7fTwvc3R5bGU+PHRhYmxlIGRhdGEtcXVhcnRvLWRpc2FibGUtcHJvY2Vzc2luZz0ndHJ1ZScgY2xhc3M9J2NsLTI5ZGEwMDI4Jz4KCmBgYAoKPGNhcHRpb24gc3R5bGU9ImRpc3BsYXk6dGFibGUtY2FwdGlvbjsiPihcI3RhYjpwcm9ncmFtcyk8c3Bhbj5Qcm9ncmFtcyBuZWVkZWQgZm9yIGdlbmV0aWMgZXBpZGVtaW9sb2d5Ljwvc3Bhbj48L2NhcHRpb24+CgpgYGB7PWh0bWx9Cgo8dGhlYWQ+PHRyIHN0eWxlPSJvdmVyZmxvdy13cmFwOmJyZWFrLXdvcmQ7Ij48dGggY2xhc3M9ImNsLTI5ZDY2OTIyIj48cCBjbGFzcz0iY2wtMjlkNjU2MTIiPjxzcGFuIGNsYXNzPSJjbC0yOWQzNDM4YyI+UHJvZ3JhbTwvc3Bhbj48L3A+PC90aD48dGggY2xhc3M9ImNsLTI5ZDY2OTJjIj48cCBjbGFzcz0iY2wtMjlkNjU2MTIiPjxzcGFuIGNsYXNzPSJjbC0yOWQzNDM4YyI+TGluazwvc3Bhbj48L3A+PC90aD48dGggY2xhc3M9ImNsLTI5ZDY2OTJkIj48cCBjbGFzcz0iY2wtMjlkNjU2MTIiPjxzcGFuIGNsYXNzPSJjbC0yOWQzNDM4YyI+RGVzY3JpcHRpb248L3NwYW4+PC9wPjwvdGg+PC90cj48L3RoZWFkPjx0Ym9keT48dHIgc3R5bGU9Im92ZXJmbG93LXdyYXA6YnJlYWstd29yZDsiPjx0ZCBjbGFzcz0iY2wtMjlkNjY5MzYiPjxwIGNsYXNzPSJjbC0yOWQ2NTYxMiI+PHNwYW4gY2xhc3M9ImNsLTI5ZDM0MzhjIj5QTElOSzwvc3Bhbj48L3A+PC90ZD48dGQgY2xhc3M9ImNsLTI5ZDY2OTM3Ij48cCBjbGFzcz0iY2wtMjlkNjU2MTIiPjxzcGFuIGNsYXNzPSJjbC0yOWQzNDM4YyI+aHR0cHM6Ly93d3cuY29nLWdlbm9taWNzLm9yZy9wbGluazIvPC9zcGFuPjwvcD48L3RkPjx0ZCBjbGFzcz0iY2wtMjlkNjY5MzgiPjxwIGNsYXNzPSJjbC0yOWQ2NTYxMiI+PHNwYW4gY2xhc3M9ImNsLTI5ZDM0MzhjIj5QTElOSyBpcyBhIGZyZWUsIG9wZW4tc291cmNlIGdlbmV0aWMgYW5hbHlzaXMgdG9vbCBzZXQsIGRlc2lnbmVkIHRvIHBlcmZvcm0gYSByYW5nZSBvZiBiYXNpYyBkYXRhIHBhcnNpbmcgYW5kIHF1YWxpdHkgY29udHJvbCwgYXMgd2VsbCBhcyBiYXNpYyBhbmQgbGFyZ2Utc2NhbGUgYW5hbHlzZXMgaW4gYSBjb21wdXRhdGlvbmFsbHkgZWZmaWNpZW50IG1hbm5lci48L3NwYW4+PC9wPjwvdGQ+PC90cj48dHIgc3R5bGU9Im92ZXJmbG93LXdyYXA6YnJlYWstd29yZDsiPjx0ZCBjbGFzcz0iY2wtMjlkNjY5MzYiPjxwIGNsYXNzPSJjbC0yOWQ2NTYxMiI+PHNwYW4gY2xhc3M9ImNsLTI5ZDM0MzhjIj5SPC9zcGFuPjwvcD48L3RkPjx0ZCBjbGFzcz0iY2wtMjlkNjY5MzciPjxwIGNsYXNzPSJjbC0yOWQ2NTYxMiI+PHNwYW4gY2xhc3M9ImNsLTI5ZDM0MzhjIj5odHRwczovL2NyYW4uci1wcm9qZWN0Lm9yZy88L3NwYW4+PC9wPjwvdGQ+PHRkIGNsYXNzPSJjbC0yOWQ2NjkzOCI+PHAgY2xhc3M9ImNsLTI5ZDY1NjEyIj48c3BhbiBjbGFzcz0iY2wtMjlkMzQzOGMiPkEgcHJvZ3JhbSB0byBwZXJmb3JtIHN0YXRpc3RpY2FsIGFuYWx5c2lzIGFuZCB2aXN1YWxpemF0aW9ucy48L3NwYW4+PC9wPjwvdGQ+PC90cj48dHIgc3R5bGU9Im92ZXJmbG93LXdyYXA6YnJlYWstd29yZDsiPjx0ZCBjbGFzcz0iY2wtMjlkNjY5MzYiPjxwIGNsYXNzPSJjbC0yOWQ2NTYxMiI+PHNwYW4gY2xhc3M9ImNsLTI5ZDM0MzhjIj5SU3R1ZGlvPC9zcGFuPjwvcD48L3RkPjx0ZCBjbGFzcz0iY2wtMjlkNjY5MzciPjxwIGNsYXNzPSJjbC0yOWQ2NTYxMiI+PHNwYW4gY2xhc3M9ImNsLTI5ZDM0MzhjIj5odHRwczovL3d3dy5yc3R1ZGlvLmNvbTwvc3Bhbj48L3A+PC90ZD48dGQgY2xhc3M9ImNsLTI5ZDY2OTM4Ij48cCBjbGFzcz0iY2wtMjlkNjU2MTIiPjxzcGFuIGNsYXNzPSJjbC0yOWQzNDM4YyI+QSB1c2VyLWZyaWVuZGx5IFItd3JhcC1hcm91bmQgZm9yIGNvZGUgZWRpdGluZywgZGVidWdnaW5nLCBhbmFseXNlcywgYW5kIHZpc3VhbGl6YXRpb24uPC9zcGFuPjwvcD48L3RkPjwvdHI+PHRyIHN0eWxlPSJvdmVyZmxvdy13cmFwOmJyZWFrLXdvcmQ7Ij48dGQgY2xhc3M9ImNsLTI5ZDY2OTQwIj48cCBjbGFzcz0iY2wtMjlkNjU2MTIiPjxzcGFuIGNsYXNzPSJjbC0yOWQzNDM4YyI+SG9tZWJyZXc8L3NwYW4+PC9wPjwvdGQ+PHRkIGNsYXNzPSJjbC0yOWQ2Njk0MSI+PHAgY2xhc3M9ImNsLTI5ZDY1NjEyIj48c3BhbiBjbGFzcz0iY2wtMjlkMzQzOGMiPmh0dHBzOi8vYnJldy5zaDwvc3Bhbj48L3A+PC90ZD48dGQgY2xhc3M9ImNsLTI5ZDY2OTQyIj48cCBjbGFzcz0iY2wtMjlkNjU2MTIiPjxzcGFuIGNsYXNzPSJjbC0yOWQzNDM4YyI+QSBncmVhdCBleHRlbnNpb24gZm9yIE1hYy11c2VycyB0byBpbnN0YWxsIHJlYWxseSB1c2VmdWwgcHJvZ3JhbXMgdGhhdCBBcHBsZSBkaWRuJ3QuPC9zcGFuPjwvcD48L3RkPjwvdHI+PC90Ym9keT48L3RhYmxlPjwvZGl2PgpgYGAKCiMjIyBSU3R1ZGlvCioqUlN0dWRpbyoqIGlzIGEgdmVyeSB1c2VyLWZyaWVuZGx5IGludGVyZmFjZSBhcm91bmQgYFJgIHRoYXQgbWFrZXMgeW91ciBgUmAtc2NyaXB0aW5nLWxpZmUgYSBsb3QgZWFzaWVyLiBZb3Ugc2hvdWxkIGdldCB1c2VkIHRvIHRoYXQuICoqUlN0dWRpbyoqIGNvbWVzIHdpdGggYFJgIHNvIHlvdSBkb24ndCBoYXZlIHRvIHdvcnJ5IGFib3V0IHRoYXQuCgojIyMgUExJTksKUmlnaHQsIG9udG8gYFBMSU5LYC4gCgpBbGwgZ2VuZXRpYyBhbmFseXNlcyBjYW4gYmUgZG9uZSBpbiBQTElOSywgZXZlbiBvbiB5b3VyIGxhcHRvcCwgYnV0IHdpdGggbGFyZ2UgZGF0YXNldHMsIGZvciBleGFtcGxlIFtVSyBCaW9iYW5rXShodHRwczovL3d3dy51a2Jpb2JhbmsuYWMudWspe3RhcmdldD0iX2JsYW5rIn0gc2l6ZSwgaXQgaXMgYmV0dGVyIHRvIHN3aXRjaCB0byBhIFtoaWdoLXBlcmZvcm1hbmNlIGNvbXB1dGluZyBjbHVzdGVyIChIUEMpXShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9IaWdoLXBlcmZvcm1hbmNlX2NvbXB1dGluZyl7dGFyZ2V0PSJfYmxhbmsifSBsaWtlIHdlIGhhdmUgYXZhaWxhYmxlIGF0IHRoZSBbVXRyZWNodCBTY2llbmNlIFBhcmtdKGh0dHBzOi8vd2lraS5iaW9pbmZvcm1hdGljcy51bWN1dHJlY2h0Lm5sL2Jpbi92aWV3L0hQQy9XZWJIb21lKXt0YXJnZXQ9Il9ibGFuayJ9LiBUaGUgb3JpZ2luYWwgUExJTksgdjEuMDcgY2FuIGJlIGZvdW5kIFtoZXJlXShodHRwczovL3p6ei5id2guaGFydmFyZC5lZHUvcGxpbmsvaW5kZXguc2h0bWwpe3RhcmdldD0iX2JsYW5rIn0sIGJ1dCBub3dhZGF5cyB3ZSBhcmUgdXNpbmcgYSBuZXdlciwgZmFzdGVyIHZlcnNpb246ICoqUExJTksgdjEuOSoqIHdoaWNoIGNhbiBiZSBmb3VuZCBbaGVyZV0oaHR0cHM6Ly93d3cuY29nLWdlbm9taWNzLm9yZy9wbGluazIpe3RhcmdldD0iX2JsYW5rIn0uIEl0IHN0aWxsIHNheXMgJ1BMSU5LIDEuOTAgYmV0YScgKEZpZ3VyZSBcQHJlZihmaWc6cGxpbmtwcm9ncmFtKSksIGJ1dCB5b3UgY2FuIGNvbnNpZGVyIHRoaXMgdmVyc2lvbiBzdGFibGUgYW5kIHNhdmUgdG8gd29yayB3aXRoLCBidXQgYXMgeW91IGNhbiBzZWUsIHNvbWUgZnVuY3Rpb25zIGFyZSBub3Qgc3VwcG9ydGVkIGFueW1vcmUuCgo8ZGl2IGNsYXNzPSJmaWd1cmUiIHN0eWxlPSJ0ZXh0LWFsaWduOiBjZW50ZXIiPgo8aW1nIHNyYz0iaW1nL3BsaW5rLnBuZyIgYWx0PSJUaGUgUExJTksgdjEuOSB3ZWJzaXRlLiIgd2lkdGg9Ijg1JSIgLz4KPHAgY2xhc3M9ImNhcHRpb24iPihcI2ZpZzpwbGlua3Byb2dyYW0pVGhlIFBMSU5LIHYxLjkgd2Vic2l0ZS48L3A+CjwvZGl2PgoKCiMjIyBBbHRlcm5hdGl2ZXMgdG8gYFBMSU5LYApOb3dhZGF5cywgYSBsb3Qgb2YgcGVvcGxlIGFsc28gdXNlIHByb2dyYW1zIGxpa2UgW1NOUFRFU1RdKHNucHRlc3Qpe3RhcmdldD0iX2JsYW5rIn0sIFtCT0xULUxNTV0oaHR0cHM6Ly9kYXRhLmJyb2FkaW5zdGl0dXRlLm9yZy9hbGtlc2dyb3VwL0JPTFQtTE1NLyl7dGFyZ2V0PSJfYmxhbmsifSwgIFtHQ1RBXShodHRwOi8vY25zZ2Vub21pY3MuY29tL3NvZnR3YXJlL2djdGEvI092ZXJ2aWV3KXt0YXJnZXQ9Il9ibGFuayJ9LCBvciBbcmVnZW5pZV0oaHR0cHM6Ly9yZ2NnaXRodWIuZ2l0aHViLmlvL3JlZ2VuaWUvKXt0YXJnZXQ9Il9ibGFuayJ9IGFzIGFsdGVybmF0aXZlcyB0byBleGVjdXRlIEdXQVMuIFRoZXNlIHByb2dyYW1zIHdlcmUgZGVzaWduZWQgd2l0aCBzcGVjaWZpYyB1c2UtY2FzZXMgaW4gbWluZCwgZm9yIGluc3RhbmNlIHJlYWxseSBsYXJnZSBiaW9iYW5rIGRhdGEgaW5jbHVkaW5nIGh1bmRyZWRzIG9mIHRob3VzYW5kcyBpbmRpdmlkdWFscywgYmV0dGVyIGNvbnRyb2wgZm9yIHBvcHVsYXRpb24gc3RyYXRpZmljYXRpb24sIHRoZSBhYmlsaXR5IHRvIGVzdGltYXRlIHRyYWl0IGhlcml0YWJpbGl0eSBvciBGc3QsIGFuZCBzbyBvbi4KCiMjIyBPdGhlciBwcm9ncmFtcwpNZW5kZWxpYW4gcmFuZG9taXphdGlvbiBjYW4gYmUgZG9uZSBlaXRoZXIgd2l0aCB0aGUgW1NNUl0oaHR0cDovL2Nuc2dlbm9taWNzLmNvbS9zb2Z0d2FyZS9zbXIvI092ZXJ2aWV3KXt0YXJnZXQ9Il9ibGFuayJ9IG9yIFtHU01SXShodHRwOi8vY25zZ2Vub21pY3MuY29tL3NvZnR3YXJlL2dzbXIvKXt0YXJnZXQ9Il9ibGFuayJ9IGZ1bmN0aW9uIGZyb20gR0NUQSwgb3Igd2l0aCBSLXBhY2thZ2VzLCBsaWtlIFtgVHdvU2FtcGxlTVJgXShodHRwczovL21yY2lldS5naXRodWIuaW8vVHdvU2FtcGxlTVIvKXt0YXJnZXQ9Il9ibGFuayJ9LgoKCiMjIENvQ2FsYwoKPiBbIFRFWFQgTkVFRFMgVVBEQVRJTkddCgpOb3csIHBheSBhdHRlbnRpb24uIElmIHlvdSBjYW1lIGhlcmUgdGhyb3VnaCB0aGUgY291cnNlICoqR2VuZXRpYyBFcGlkZW1pb2xvZ3kqKiwgeW91IGRvbid0IGhhdmUgdG8gZG8gYW55dGhpbmcuIEFsbCB0aGUgZGF0YSB5b3UgbmVlZCBhcmUgYWxyZWFkeSBkb3dubG9hZGVkLiAKCkhvd2V2ZXIsIHdoZW4geW91IGFyZSB1c2luZyB0aGlzIGJvb2sgYXMgYSBzdGFuZGFsb25lLCB5b3UnbGwgbmVlZCB0byBzdGFydCBieSBkb3dubG9hZGluZyB0aGUgZGF0YSB5b3UgbmVlZCBmb3IgdGhpcyBwcmFjdGljYWwgdG8geW91ciBEZXNrdG9wLiAKCkZvciB0aGUgY291cnNlIHdlIHNldCB1cCBhIENvQ2FsYyBTZXJ2ZXIgYW5kIGV2ZXJ5dGhpbmcgc2hvdWxkIGJlIGZpbmU7IHdlIGluc3RhbGxlZCBldmVyeXRoaW5nIHlvdSBuZWVkLiAKCiMjIFN0YW5kYWxvbmUKClNvLCB5b3UgcGxhbiB0byB1c2UgdGhpcyBib29rIGFzICdTdGFuZGFsb25lJyBvbiBhIG1hY09TIGVudmlyb25tZW50LiBUaGlzIG1lYW5zIHlvdSdsbCBuZWVkIHRvIGluc3RhbGwgYSBmZXcgdGhpbmdzIGZpcnN0LgoKIyMjIFRoZSBkYXRhIHlvdSBuZWVkCgpZb3UnbGwgbmVlZCB0byBzdGFydCBieSBkb3dubG9hZGluZyB0aGUgZGF0YSB5b3UgbmVlZCBmb3IgdGhpcyBwcmFjdGljYWwgdG8geW91ciBEZXNrdG9wLiAKCkhlcmUncyB0aGUgbGluayB0byB0aGUgZGF0YS4gCgpbTGluayB0byBHb29nbGUgRHJpdmUgd2l0aCBkYXRhXShodHRwczovL2RyaXZlLmdvb2dsZS5jb20vZHJpdmUvZm9sZGVycy8xaURMQjF5NTM0RGZnRVpOUENZQnJJajVYN2dfWGxCYmE/dXNwPXNoYXJlX2xpbmspe3RhcmdldD0iX2JsYW5rIn0KCk1ha2Ugc3VyZSB5b3UgcHV0IHRoZSBkYXRhIGluIHRoZSBgfi9EZXNrdG9wL3ByYWN0aWNhbC9gIGZvbGRlci4KClRoZSBkYXRhIGFyZSBwcmV0dHkgbGFyZ2UgKGFwcHJveC4gMTVHYiksIHNvIHRoaXMgd2lsbCB0YWtlIGEgbWludXRlIG9yIHR3byBkZXBlbmRpbmcgb24geW91ciBpbnRlcm5ldCBjb25uZWN0aW9uLiBUaW1lIHRvIHN0cmV0Y2ggeW91ciBsZWdzIG9yIGdyYWIgYSBjb2ZmZWUgKGRhdGEgc2NpZW50aXN0cyBkb24ndCBkcmluayB0ZWEpLiAKCiMjIyBUZXJtaW5hbCAKCkZvciBhbGwgdGhlIHByb2dyYW1zIHdlIHVzZSwgZXhjZXB0ICoqUlN0dWRpbyoqLCB5b3Ugd2lsbCBuZWVkIHRoZSAqKlRlcm1pbmFsKiouIFRoaXMgY29tZXMgd2l0aCBldmVyeSBtYWpvciBvcGVyYXRpbmcgc3lzdGVtOyBvbiBXaW5kb3dzIGl0IGlzIGNhbGxlZCAnUG93ZXJTaGVsbCcsIGJ1dCBsZXQncyBub3QgZ28gdGhlcmUuIEFuZCByZWdhcmRsZXNzLCB5b3Ugd2lsbCAoaGF2ZSB0byBzdGFydCB0bykgbWFrZSB5b3VyIG93biBzY3JpcHRzLiBUaGUgYmVuZWZpdCBvZiB1c2luZyBzY3JpcHRzIGlzIHRoYXQgZWFjaCBzdGVwIGluIHlvdXIgd29ya2Zsb3cgaXMgY2xlYXJseSBzdGlwdWxhdGVkIGFuZCBhbm5vdGF0ZWQsIGFuZCBpdCBhbGxvd3MgZm9yIGdyZWF0ZXIgcmVwcm9kdWNpYmlsaXR5LCBlYXNpZXIgdHJvdWJsZXNob290aW5nLCBhbmQgc2NhbGluZyB1cCB0byBoaWdoLXBlcmZvcm1hbmNlIGNvbXB1dGVyIGNsdXN0ZXJzLgoKT3BlbiB0aGUgKipUZXJtaW5hbCoqLCBpdCBzaG91bGQgYmUgb24gdGhlIGxlZnQgaW4gdGhlIHRvb2xiYXIgYXMgYSBsaXR0bGUgYmxhY2sgY29tcHV0ZXItbW9uaXRvci1saWtlIGljb24uIE1hYyB1c2VycyBjYW4gdHlwZSBgY29tbWFuZCArIHNwYWNlYCBhbmQgdHlwZSBgdGVybWluYWxgLCBhICoqVGVybWluYWwqKiBzY3JlZW4gc2hvdWxkIG9wZW4uCgo+IEZyb20gbm93IG9uIHdlIHdpbGwgdXNlIGxpdHRsZSBjb2RlIGJsb2NrcyBsaWtlIHRoZSBleGFtcGxlIHRvIGluZGljYXRlIGEgY29kZSB5b3Ugc2hvdWxkIHR5cGUvY29weS1wYXN0ZSBhbmQgaGl0IGVudGVyLiBJZiBhIGNvZGUgaXMgZm9sbG93ZWQgYnkgYSBjb21tZW50LCBpdCBpcyBpbmRpY2F0ZWQgYnkgYSAjIC0geW91IGRvbid0IG5lZWQgdG8gY29weS1wYXN0ZSBhbmQgZXhlY3V0ZSB0aGlzLgoKYGBgCkNPREUgQkxPQ0sKCkNPREUgQkxPQ0sgIyBzb21lIGNvbW1lbnQgaGVyZQpgYGAKCiMjIyBOYXZpZ2F0aW5nIHRoZSBUZXJtaW5hbAoKWW91IGNhbiBuYXZpZ2F0ZSBhcm91bmQgdGhlIGNvbXB1dGVyIHRocm91Z2ggdGhlIHRlcm1pbmFsIGJ5IHR5cGluZyBgY2QgPHBhdGg+YDsgYGNkYCBzdGFuZHMgZm9yICJjaGFuZ2UgZGlyZWN0b3J5IiBhbmQgYDxwYXRoPmAgbWVhbnMgInNvbWVfZmlsZV9kaXJlY3RvcnlfeW91X3dhbnRfdG9fZ29fdG8iLgoKClRoaXMgY29tbWFuZCB3aWxsIGJyaW5nIHlvdSB0byB5b3VyIGhvbWUgZGlyZWN0b3J5LgoKYGBgCmNkIH4gCmBgYAoKVGhpcyB3aWxsIGJyaW5nIHlvdSB0byB0aGUgcGFyZW50IGRpcmVjdG9yeSAodXAgb25lIGxldmVsKS4KCmBgYApjZCAuLi8gCmBgYAoKVGhpcyB3aWxsIGJyaW5nIHlvdSB0byB0aGUgWFhYIGRpcmVjdG9yeS4KCmBgYApjZCBYWFggCmBgYAoKCkxldCdzIG5hdmlnYXRlIHRvIHRoZSBmb2xkZXIgeW91IGp1c3QgZG93bmxvYWRlZC4KCmBgYApjZCB+L0Rlc2t0b3AvcHJhY3RpY2FsCmBgYAoKCkxldCdzIGNoZWNrIG91dCB3aGF0IGlzIGluc2lkZSB0aGUgZGlyZWN0b3J5LCBieSBsaXN0aW5nIChgbHNgKSBpdHMgY29udGVudHMuCgpUaGlzIGNvbW1hbmQgc2hvd3MgZmlsZXMgYXMgbGlzdDsgdGhlIGAtbGAgbWFrZXMgaXQgYSB2ZXJ0aWNhbCBsaXN0IGFuZCBhZGRzIG1vcmUgaW5mb3JtYXRpb24sIHlvdSBjYW4gYWxzbyByZW1vdmUgaXQgYW5kIHNpbXBseSB0eXBlIGBsc2AgLSBnbyBvbiwgYW5kIHRyeS4KCmBgYApscyAtbCAKYGBgCgoKVGhpcyBjb21tYW5kIHNob3dzIGZpbGVzIGFzIGxpc3Qgd2l0aCBodW1hbiByZWFkYWJsZSBmb3JtYXQuCgpgYGAKbHMgLWxoIApgYGAKQWRkaW5nIHRoZSBmbGFncyBgLWxoYCB3aWxsIGdldCB5b3UgdGhlIGNvbnRlbnRzIG9mIGEgZGlyZWN0b3J5IGluIGEgbGlzdCAoYC1sYCkgYW5kIG1ha2UgdGhlIHNpemUgJ2h1bWFuLXJlYWRhYmxlJyAoYC1oYCkuCgpBZGRpbmcgYC10YCBzaG93cyB0aGUgZmlsZXMgYXMgbGlzdCBzb3J0ZWQgYnkgdGltZSBlZGl0ZWQuCgpgYGAKbHMgLWx0IApgYGAKCkFkZGluZyBgLVNgIHNob3dzIHRoZSBmaWxlcyBhcyBsaXN0IHNvcnRlZCBieSBzaXplLgoKYGBgCmxzIC1sUyAKYGBgCgpZb3UgY2FuIGFsc28gY291bnQgdGhlIG51bWJlciBvZiBmaWxlcy4gSnVzdCAncGlwZScgdGhlIHJlc3VsdCBmcm9tIGBsc2AgdG8gdGhlIG5leHQgcHJvZ3JhbSBgd2NgICgnd29yZGNvdW50JykgYW5kIGxpc3QgdGhlIG51bWJlciBvZiBsaW5lcywgYC1sYC4gSW4gdGhpcyBjYXNlIGAtbGAgaXMgYSBmbGFnIHVzZWQgYnkgYHdjYCBhbmQgaXQgaGFzIGEgZGlmZmVyZW50IG1lYW5pbmcgdGhhbiBpdCBkb2VzIGZvciBgbHNgLiAKCmBgYApscyB8IHdjIC1sCmBgYAoKQW5kIGlmIHlvdSB3YW50IHRvIGtub3cgYWxsIHRoZSBmdW5jdGlvbiBvZiBhIHByb2dyYW0gc2ltcGx5IHR5cGUgdGhlIGZvbGxvd2luZy4KCmBgYAptYW4gbHMKYGBgCgpUaGlzIHdpbGwgdGFrZSB5b3UgdG8gYSBtYW51YWwgb2YgdGhlIHByb2dyYW0gd2l0aCBhbiBleHRlbnNpdmUgZGVzY3JpcHRpb24gb2YgZWFjaCBmbGFnIChGaWd1cmUgXEByZWYoZmlnOmxzbWFudWFsKSkuCgo8ZGl2IGNsYXNzPSJmaWd1cmUiIHN0eWxlPSJ0ZXh0LWFsaWduOiBjZW50ZXIiPgo8aW1nIHNyYz0iaW1nL2xzX21hbnVhbC5wbmciIGFsdD0iUGFydGlhbCBvdXRwdXQgZnJvbSB0aGUgbHMgbWFudWFsLiIgd2lkdGg9Ijg1JSIgLz4KPHAgY2xhc3M9ImNhcHRpb24iPihcI2ZpZzpsc21hbnVhbClQYXJ0aWFsIG91dHB1dCBmcm9tIHRoZSBscyBtYW51YWwuPC9wPgo8L2Rpdj4KCiMjIyBJbnN0YWxsaW5nIHRoZSBzb2Z0d2FyZQoKIyMjIyBicmV3CgpMaW51eCBoYXMgYSBncmVhdCBwYWNrYWdlLW1hbmFnZXIgdGhhdCBpcyBsYWNraW5nIG9uIG1hY09TLiBZb3UgY2FuIGluc3RhbGwgW2BicmV3YF0oaHR0cHM6Ly9icmV3LnNoKXt0YXJnZXQ9Il9ibGFuayJ9IHRvIGNvbXBlbnNhdGUgZm9yIHRoaXMuIFRoaXMgYWRkcyB0aGUgYWJpbGl0eSB0byBpbnN0YWxsIGFsbW9zdCBhbnkgTGludXgtYmFzZWQgcHJvZ3JhbSB0aHJvdWdoIHRoZSAqKlRlcm1pbmFsKiogc3VjaCBhcyBgd2dldGAsIGBsbHZtYCwgZXRjLiAKCk9wZW4gKipUZXJtaW5hbCoqIGFuZCBleGVjdXRlIHRoZSBmb2xsb3dpbmc6CgpgYGAKL2Jpbi9iYXNoIC1jICIkKGN1cmwgLWZzU0wgaHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL0hvbWVicmV3L2luc3RhbGwvSEVBRC9pbnN0YWxsLnNoKSIKYGBgCgpDaGVjayBpZiBldmVyeXRoaW5nIGlzIGluIG9yZGVyLgoKYGBgCmJyZXcgZG9jdG9yCmBgYAoKSXQgc2hvdWxkbid0IHJlcG9ydCBhbnkgZXJyb3JzLgoKIyMjIyBQTElOSwoKRmlyc3QsIHdlJ2xsIGdldCBgUExJTktgLiBOYXZpZ2F0ZSB0byB0aGUgKipQTElOSyB2MS45Kiogd2Vic2l0ZSwgd2hpY2ggY2FuIGJlIGZvdW5kIFtoZXJlXShodHRwczovL3d3dy5jb2ctZ2Vub21pY3Mub3JnL3BsaW5rMil7dGFyZ2V0PSJfYmxhbmsifS4gRG93bmxvYWQgdGhlIG1hY09TICg2NC1iaXQpIHZlcnNpb24gdW5kZXIgJ1N0YWJsZSAoYmV0YSB4LngsIGRheSBtb250aCB5ZWFyKScuIAoKPiBOb3RlOiBBcHBsZSBwcm9kdWNlZCBJbnRlbC1iYXNlZCBjb21wdXRlcnMgZm9yIGEgZmV3IHllYXJzIGJhY2ssIGFuZCBtb3N0IHByb2dyYW1zLCBwYWNrYWdlcywgbGlicmFyaWVzIGFuZCB3aGF0bm90IGFyZSBkZXNpZ25lZCBmb3IgdGhhdC4gU28sIEkgaGlnaGx5IHJlY29tbWVuZCB1c2luZyBzb2Z0d2FyZSBkZXNpZ25lZCBmb3IgdGhhdCBhbmQgYWN0aXZhdGluZyBSb3NldHRhMiBpbiB5b3VyIFRlcm1pbmFsLiBEb24ndCBrbm93IGhvdyB0byBkbyB0aGF0PyBGb2xsb3dpbmcgW3RoZXNlIGluc3RydWN0aW9uc10oaHR0cHM6Ly9zdXBwb3J0LmFwcGxlLmNvbS9lbi11cy8xMDI1Mjcpe3RhcmdldD0iX2JsYW5rIn0uCgpVbnppcCB0aGUgZm9sZGVyIGFuZCBwdXQgYHBsaW5rYCBpbiB0aGUgcHJhY3RpY2FsIGZvbGRlci4gCgpgYGAKbXYgLXYgfi9Eb3dubG9hZHMvcGxpbmtfbWFjXzIwMjMxMjExL3BsaW5rIH4vRGVza3RvcC9wcmFjdGljYWwvcGxpbmsgCmBgYAoKIyMjIyBJbnN0YWxsaW5nIFIgYW5kIFJTdHVkaW8KCkxldCdzIGdvIGFoZWFkIGFuZCB1c2UgYGJyZXdgIHRvIGluc3RhbGwgdGhlIGBSYCBhbmQgKipSU3R1ZGlvKiogc29mdHdhcmUuCgpJbiAqKlRlcm1pbmFsKiogZXhlY3V0ZSB0aGUgZm9sbG93aW5nIGFuZCBqdXN0IGZvbGxvdyB0aGUgaW5zdHJ1Y3Rpb25zLgoKYGBgCmJyZXcgaW5zdGFsbCByc3R1ZGlvCmJyZXcgaW5zdGFsbCAtLWNhc2sgcgpgYGAKCk5vdyBjbG9zZSB0aGUgdGVybWluYWwgd2luZG93IC0gcmVhbGx5IG1ha2Ugc3VyZSB0aGF0IHRoZSB0ZXJtaW5hbC1wcm9ncmFtIGhhcyBxdWl0LgoKT3BlbiB5b3VyIGZyZXNoIGluc3RhbGxhdGlvbiBvZiAqKlJTdHVkaW8qKiBieSBkb3VibGUgY2xpY2tpbmcgdGhlIGljb24uIFlvdSBzaG91bGQgYmUgc2VlaW5nIHNvbWV0aGluZyBsaWtlIGZpZ3VyZSBcQHJlZihmaWc6cnN0dWRpb3NjcmVlbnNob3QpCgo8ZGl2IGNsYXNzPSJmaWd1cmUiIHN0eWxlPSJ0ZXh0LWFsaWduOiBjZW50ZXIiPgo8aW1nIHNyYz0iaW1nL3JzdHVkaW8tc2NyZWVuc2hvdC5wbmciIGFsdD0iUlN0dWRpbyBzY3JlZW5zaG90LiIgd2lkdGg9Ijg1JSIgLz4KPHAgY2xhc3M9ImNhcHRpb24iPihcI2ZpZzpyc3R1ZGlvc2NyZWVuc2hvdClSU3R1ZGlvIHNjcmVlbnNob3QuPC9wPgo8L2Rpdj4KCgpJbiB0aGUgdG9wIHJpZ2h0LCB5b3Ugc2VlIGEgbGl0dGxlIGdyZWVuLXdoaXRlIHBsdXMtc2lnbiwgY2xpY2sgdGhpcyBhbmQgc2VsZWN0ICdSIE5vdGVib29rJyAoRmlndXJlIFxAcmVmKGZpZzpyc3R1ZGlvc2NyZWVuc2hvdGNyZWF0ZW5vdGVib29rKSkuIAoKPGRpdiBjbGFzcz0iZmlndXJlIiBzdHlsZT0idGV4dC1hbGlnbjogY2VudGVyIj4KPGltZyBzcmM9ImltZy9yc3R1ZGlvLXNjcmVlbnNob3QtY3JlYXRlLW5vdGVib29rLnBuZyIgYWx0PSJSU3R1ZGlvIHNjcmVlbnNob3QuIiB3aWR0aD0iODUlIiAvPgo8cCBjbGFzcz0iY2FwdGlvbiI+KFwjZmlnOnJzdHVkaW9zY3JlZW5zaG90Y3JlYXRlbm90ZWJvb2spUlN0dWRpbyBzY3JlZW5zaG90LjwvcD4KPC9kaXY+CgpZb3Ugd2lsbCBjcmVhdGUgYW4gdW50aXRsZWQgKGBVbnRpdGxlZDFgKSBgUmAgbm90ZWJvb2s6IHlvdSBjYW4gY29tYmluZSB0ZXh0IGRlc2NyaXB0aW9ucywgbGlrZSB5b3Ugd291bGQgaW4gYSBsYWItam91cm5hbCwgd2l0aCBjb2RlLXNlY3Rpb25zLiBSZWFkIHdoYXQgaXMgaW4gdGhlIG5vdGVib29rIHRvIGdldCBhIGdyYXNwIG9uIHRoYXQgKEZpZ3VyZSBcQHJlZihmaWc6cnN0dWRpb3NjcmVlbnNob3Rub3RlYm9vaykpLiAKCjxkaXYgY2xhc3M9ImZpZ3VyZSIgc3R5bGU9InRleHQtYWxpZ246IGNlbnRlciI+CjxpbWcgc3JjPSJpbWcvcnN0dWRpby1zY3JlZW5zaG90LW5vdGVib29rLnBuZyIgYWx0PSJSU3R1ZGlvIHNjcmVlbnNob3QuIiB3aWR0aD0iODUlIiAvPgo8cCBjbGFzcz0iY2FwdGlvbiI+KFwjZmlnOnJzdHVkaW9zY3JlZW5zaG90bm90ZWJvb2spUlN0dWRpbyBzY3JlZW5zaG90LjwvcD4KPC9kaXY+CgpSaWdodCwgeW91IHNob3VsZCBiZSBpbnN0YWxsaW5nIHNvbWUgcGFja2FnZXMuIFRvIGRvIHNvLCB5b3UgY2FuIHJlbW92ZSBgcGxvdChjYXJzKWAgKG9yIGxlYXZlIGFuZCBjcmVhdGUgYSBuZXcgY29kZS1ibG9jayBhcyBwZXIgaW5zdHJ1Y3Rpb25zIGluIHRoZSBub3RlYm9vayksIGFuZCBjb3B5IHBhc3RlIHRoZSBjb2RlIGJlbG93LiBNYWtlIHN1cmUgdG8gcHV0IGluIGEgY29kZSBibG9jayBsaWtlIHRoZSBleGFtcGxlIGluIHdoaWNoIGBwbG90KGNhcnMpYCBpcyBpbi4KCmBgYApyZW1vdGVzOjppbnN0YWxsX2dpdGh1YihjKCJyc3R1ZGlvL3JtYXJrZG93biIpKQoKaW5zdGFsbC5wYWNrYWdlcyhjKCJmb3JtYXRSIiwgInJlbW90ZXMiLCAKICAgICAgICAgICAgICAgICAgICJodHRyIiwgInVzZXRoaXMiLCAKICAgICAgICAgICAgICAgICAgICJkYXRhLnRhYmxlIiwgImRldnRvb2xzIiwgCiAgICAgICAgICAgICAgICAgICAiZHBseXIiLCAidGliYmxlIiwgInRpZHl2ZXJzZSIsIAogICAgICAgICAgICAgICAgICAgIm9wZW54bHN4IiwKICAgICAgICAgICAgICAgICAgICJnZ3Bsb3QyIiwKICAgICAgICAgICAgICAgICAgICJnZ3NjaSIsICJnZ3RoZW1lcyIsCiAgICAgICAgICAgICAgICAgICAicXFtYW4iLCAiQ01wbG90IiwgInBsb3RseSIsIAogICAgICAgICAgICAgICAgICAgIm9wZW54bHN4IikpCmRldnRvb2xzOjppbnN0YWxsX2dpdGh1Yigia2Fzc2FtYmFyYS9nZ3B1YnIiKQoKZGV2dG9vbHM6Omluc3RhbGxfZ2l0aHViKCJvbGl2aWFzYWJpay9SQUNFUiIpCgpyZW1vdGVzOjppbnN0YWxsX2dpdGh1YigiTVJDSUVVL1R3b1NhbXBsZU1SIikKZGV2dG9vbHM6Omluc3RhbGxfZ2l0aHViKCJNUkNJRVUvTVJJbnN0cnVtZW50cyIpCgppZiAoIXJlcXVpcmUoIkJpb2NNYW5hZ2VyIiwgcXVpZXRseSA9IFRSVUUpKQogIGluc3RhbGwucGFja2FnZXMoIkJpb2NNYW5hZ2VyIikKQmlvY01hbmFnZXI6Omluc3RhbGwoImdlbmVwbG90dGVyIikKYGBgCgpZb3Ugc2hvdWxkIGxvYWQgdGhlc2UgcGFja2FnZXMgdG9vLiAKCmBgYApsaWJyYXJ5KHJtYXJrZG93bikKbGlicmFyeShmb3JtYXRSKQoKbGlicmFyeShvcGVueGxzeCkKCmxpYnJhcnkoZGF0YS50YWJsZSkKCmxpYnJhcnkodGliYmxlKQpsaWJyYXJ5KHRpZHl2ZXJzZSkKbGlicmFyeShkcGx5cikKbGlicmFyeShwbG90bHkpCgpsaWJyYXJ5KGdncGxvdDIpCmxpYnJhcnkoZGV2dG9vbHMpCmxpYnJhcnkoZ2dwdWJyKQpsaWJyYXJ5KGdnc2NpKQpsaWJyYXJ5KGdndGhlbWVzKQoKbGlicmFyeShxcW1hbikKbGlicmFyeShDTXBsb3QpCmxpYnJhcnkoUkFDRVIpCgpsaWJyYXJ5KHJlbW90ZXMpCmxpYnJhcnkoVHdvU2FtcGxlTVIpCmxpYnJhcnkoTVJJbnN0cnVtZW50cykKCmxpYnJhcnkoImdlbmVwbG90dGVyIikKYGBgCgpBbGwgaW4gYWxsIHRoaXMgbWF5IHRha2Ugc29tZSB0aW1lLCBnb29kIG1vbWVudCB0byByZWxheCwgcmV2aWV3IHlvdXIgbm90ZXMsIHN0cmV0Y2ggeW91ciBsZWdzLCBvciB0YWtlIGEgY29mZmVlLgoKCiMjIEFyZSB5b3UgcmVhZHk/CgpBcmUgeW91IHJlYWR5PyBEaWQgeW91IGJyaW5nIGNvZmZlZSBhbmQgYSBnb29kIGRvc2Ugb2YgZW5lcmd5PyBMZXQncyBzdGFydCEgCgpPaCwgb25lIG1vcmUgdGhpbmc6IHlvdSBjYW4gc2F2ZSB5b3VyIG5vdGVib29rLCB0aGUgb25lIHlvdSBqdXN0IGNyZWF0ZWQsIHRvIGtlZXAgYWxsIHRoZSBgUmAgY29kZXMgeW91IGFyZSBhcHBseWluZyBpbiB0aGUgbmV4dCBjaGFwdGVycyBhbmQgYWRkIGRlc2NyaXB0aW9ucyBhbmQgbm90ZXMuIElmIHlvdSBzYXZlIHRoaXMgbm90ZWJvb2sgeW91J2xsIG5vdGljZSB0aGF0IGEgYGh0bWxgLWZpbGUgaXMgY3JlYXRlZC4gVGhpcyBmaWxlIGlzIGEgbGVnaWJsZSB3ZWJicm93c2VyLWZyaWVuZGx5IHZlcnNpb24gb2YgeW91ciB3b3JrIGFuZCBjb250YWlucyB0aGUgY29kZXMgYW5kIHRoZSBvdXRwdXQgKGNvZGUgbWVzc2FnZXMsIHRhYmxlcywgYW5kIGZpZ3VyZXMpLiBBbmQgdGhlIG5pY2UgdGhpbmcgaXMsIHRoYXQgeW91IGNhbiBlYXNpbHkgc2hhcmUgaXQgd2l0aCBvdGhlcnMgb3ZlciBlbWFpbC4gCgpPay4gJ05vdWdoIHNhaWQsIGxldCdzIG1vdmUgb24gdG8gY292ZXIgc29tZSBiYXNpY3MgaW4gQ2hhcHRlciBcQHJlZihnd2FzLWJhc2ljcykuCgo8IS0tIGBgYHtqcywgZWNobyA9IEZBTFNFfSAtLT4KPCEtLSB0aXRsZT1kb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnaGVhZGVyJyk7IC0tPgo8IS0tIHRpdGxlLmlubmVySFRNTCA9ICc8aW1nIHNyYz0iaW1nL19oZWFkZXJzL3dvbWVuX2JlaGluZF9tYWNib29rLnBuZyIgYWx0PSJHZXR0aW5nIHN0YXJ0ZWQiPicgKyB0aXRsZS5pbm5lckhUTUwgLS0+CjwhLS0gYGBgIC0tPgoKPCEtLWNoYXB0ZXI6ZW5kOjAyXzJfZ2V0dGluZ3N0YXJ0ZWQuUm1kLS0+CgojIExpY2Vuc2VzIGFuZCBkaXNjbGFpbWVycyB7I2xpY2Vuc2V9CjwhLS0gIVtdKGltZy9faGVhZGVycy9saWNlbnNlcy5wbmcpe3dpZHRoPTEwMCV9IC0tPgoKCgoKCiMjIENvcHlyaWdodAoKVGhpcyBib29rIGFuZCBhbGwgaXRzIG1hdGVyaWFsICgiY29udGVudCIpIGlzIHByb3RlY3RlZCBieSBjb3B5cmlnaHQgdW5kZXIgRHV0Y2ggQ29weXJpZ2h0IGxhd3MgYW5kIGlzIHRoZSBwcm9wZXJ0eSBvZiB0aGUgYXV0aG9yIG9yIHRoZSBwYXJ0eSBjcmVkaXRlZCBhcyB0aGUgcHJvdmlkZXIgb2YgdGhlIGNvbnRlbnQuIFlvdSBtYXkgbm90IGNvcHksIHJlcHJvZHVjZSwgZGlzdHJpYnV0ZSwgcHVibGlzaCwgZGlzcGxheSwgcGVyZm9ybSwgbW9kaWZ5LCBjcmVhdGUgZGVyaXZhdGl2ZSB3b3JrcywgdHJhbnNtaXQsIG9yIGluIGFueSB3YXkgZXhwbG9pdCBhbnkgc3VjaCBjb250ZW50LCBub3IgbWF5IHlvdSBkaXN0cmlidXRlIGFueSBwYXJ0IG9mIHRoaXMgY29udGVudCBvdmVyIGFueSBuZXR3b3JrLCBpbmNsdWRpbmcgYSBsb2NhbCBhcmVhIG5ldHdvcmssIHNlbGwgb3Igb2ZmZXIgaXQgZm9yIHNhbGUsIG9yIHVzZSBzdWNoIGNvbnRlbnQgdG8gY29uc3RydWN0IGFueSBraW5kIG9mIGRhdGFiYXNlLiBZb3UgbWF5IG5vdCBhbHRlciBvciByZW1vdmUgYW55IGNvcHlyaWdodCBvciBvdGhlciBub3RpY2UgZnJvbSBjb3BpZXMgb2YgdGhlIGNvbnRlbnQgb24gdGhpcyB3ZWJzaXRlLiBDb3B5aW5nIG9yIHN0b3JpbmcgYW55IGNvbnRlbnQgZXhjZXB0IGFzIHByb3ZpZGVkIGFib3ZlIGlzIGV4cHJlc3NseSBwcm9oaWJpdGVkIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIG9mIHRoZSBhdXRob3Igb3IgdGhlIGNvcHlyaWdodCBob2xkZXIgaWRlbnRpZmllZCBpbiB0aGUgaW5kaXZpZHVhbCBjb250ZW50J3MgY29weXJpZ2h0IG5vdGljZS4gRm9yIHBlcm1pc3Npb24gdG8gdXNlIHRoaXMgY29udGVudCwgcGxlYXNlIGNvbnRhY3QgdGhlIGF1dGhvci4KCiMjIERpc2NsYWltZXIKClRoZSBjb250ZW50IGNvbnRhaW5lZCBoZXJlaW4gaXMgcHJvdmlkZWQgb25seSBmb3IgZWR1Y2F0aW9uYWwgYW5kIGluZm9ybWF0aW9uYWwgcHVycG9zZXMgb3IgYXMgcmVxdWlyZWQgYnkgRHV0Y2ggbGF3LiBUaGUgYXV0aG9yIGF0dGVtcHRlZCB0byBlbnN1cmUgdGhhdCBjb250ZW50IGlzIGFjY3VyYXRlIGFuZCBvYnRhaW5lZCBmcm9tIHJlbGlhYmxlIHNvdXJjZXMsIGJ1dCBkb2VzIG5vdCByZXByZXNlbnQgaXQgdG8gYmUgZXJyb3ItZnJlZS4gVGhlIGF1dGhvciBtYXkgYWRkLCBhbWVuZCBvciByZXBlYWwgYW55IHRleHQsIHByb2NlZHVyZSBvciByZWd1bGF0aW9uLCBhbmQgZmFpbHVyZSB0byB0aW1lbHkgcG9zdCBzdWNoIGNoYW5nZXMgdG8gdGhpcyBib29rIHNoYWxsIG5vdCBiZSBjb25zdHJ1ZWQgYXMgYSB3YWl2ZXIgb2YgZW5mb3JjZW1lbnQuIFRoZSBhdXRob3IgZG9lcyBub3Qgd2FycmFudCB0aGF0IGFueSBmdW5jdGlvbnMgb24gdGhpcyB3ZWJzaXRlIG9yIHRoZSBjb250ZW50cyBhbmQgcmVmZXJlbmNlcyBoZXJlaW4gd2lsbCBiZSB1bmludGVycnVwdGVkLCB0aGF0IGRlZmVjdHMgd2lsbCBiZSBjb3JyZWN0ZWQsIG9yIHRoYXQgdGhpcyB3ZWJzaXRlIG9yIHRoZSBjb250ZW50cyBhbmQgcmVmZXJlbmNlcyB3aWxsIGJlIGZyZWUgZnJvbSB2aXJ1c2VzIG9yIG90aGVyIGhhcm1mdWwgY29tcG9uZW50cy4gQW55IGxpbmtzIHRvIHRoaXJkIHBhcnR5IGluZm9ybWF0aW9uIG9uIHRoZSBhdXRob3LigJlzIHdlYnNpdGUgYXJlIHByb3ZpZGVkIGFzIGEgY291cnRlc3kgYW5kIGRvIG5vdCBjb25zdGl0dXRlIGFuIGVuZG9yc2VtZW50IG9mIHRob3NlIG1hdGVyaWFscyBvciB0aGUgdGhpcmQgcGFydHkgcHJvdmlkaW5nIHRoZW0uCgojIyBJbWFnZXMgYW5kIGRhdGEgdXNlZAoKSSB0b29rIHRoZSBhdC1tb3N0IGNhcmUgdG8gdXNlIHJlZmVyIHRvIHRoZSBvcmlnaW5hbCB3b3JrcyBhbmQgZGF0YSBzb3VyY2VzIHdoZXJlIG5lZWRlZC4gTGlrZXdpc2UsIGFsbCB0aGUgaW1hZ2VzIGMucS4gZmlndXJlcyBhcmUgZWl0aGVyIHByb2R1Y2VkIHNwZWNpZmljYWxseSBmb3IgdGhpcyBib29rLCBvciBJIHRvb2sgdGhlbSBmcm9tIFsqKlVuc3BsYXNoKipdKGh0dHBzOi8vdW5zcGxhc2guY29tL3MvcGhvdG9zL2xlZ2FsKSB0byBicmlnaHRlbiB1cCB0aGUgYm9vay4gSWYgeW91IGZlZWwgSSBtYWRlIGEgbWlzdGFrZSBhbmQgeW91ciB3b3JrIHNob3VsZCBiZSBwcm9wZXJseSByZWZlcmVuY2VkLCBwbGVhc2UgZG9uJ3QgaGVzaXRhdGUgdG8gY29udGFjdCBtZS4gCgpUaGVzZSBhcmUgdGhlIGltYWdlcyBmcm9tICoqVW5zcGxhc2gqKiBsaXN0ZWQgaGVyZSBpbiBubyBwYXJ0aWN1bGFyIG9yZGVyLgoKLSBwYXBlcnNfb25fd2FsbCAtIGh0dHBzOi8vdW5zcGxhc2guY29tL3Bob3Rvcy9vcGVuLWJvb2stbG90LU9hcWs3cXFOaF9jCi0gd29tZW5fYmVoaW5kX21hY2Jvb2sgLSBodHRwczovL3Vuc3BsYXNoLmNvbS9waG90b3Mvd29tYW4tdXNpbmctbWFjYm9vay1wcm8td2l0aC1wZXJzb24taW4td2hpdGUtdG9wLWJQVk00bk95MFJnCi0gd29tYW5fd29ya2luZ19vbl9jb2RlIC0gaHR0cHM6Ly91bnNwbGFzaC5jb20vcGhvdG9zL3dvbWFuLXdlYXJpbmctYmxhY2stdC1zaGlydC1ob2xkaW5nLXdoaXRlLWNvbXB1dGVyLWtleWJvYXJkLVlLMEhQd1dESjFJCi0gbGljZW5zZXMgLSBodHRwczovL3Vuc3BsYXNoLmNvbS9waG90b3MvYm9vay1sb3Qtb24tYmxhY2std29vZGVuLXNoZWxmLXplSC1samF3SHRnCgojIyBDb3B5cmlnaHQKCkNvcHlyaWdodCAxOTc5LTIwMjQuIEFsbCByaWdodHMgcmVzZXJ2ZWQuIFNhbmRlciBXLiB2YW4gZGVyIExhYW4gfCBbcy53LnZhbmRlcmxhYW4gW2F0XSBnbWFpbC5jb21dKG1haWx0bzpzLncudmFuZGVybGFhbkBnbWFpbC5jb20pIHwgW2h0dHBzOi8vdmFuZGVybGFhbmFuZC5zY2llbmNlXShodHRwczovL3ZhbmRlcmxhYW5hbmQuc2NpZW5jZSl7dGFyZ2V0PSJfYmxhbmsifS4gUHVibGlzaGVkIHdpdGggW2Bib29rZG93bmBdKGh0dHBzOi8vYm9va2Rvd24ub3JnL3lpaHVpL2Jvb2tkb3duLyl7dGFyZ2V0PSJfYmxhbmsifS4KCjwhLS0gYGBge2pzLCBlY2hvID0gRkFMU0V9IC0tPgo8IS0tIHRpdGxlPWRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdoZWFkZXInKTsgLS0+CjwhLS0gdGl0bGUuaW5uZXJIVE1MID0gJzxpbWcgc3JjPSJpbWcvX2hlYWRlcnMvYmFubmVyX21hbl9zdGFuZGluZ19kbmEucG5nIiBhbHQ9IkxpY2Vuc2VzIj4nICsgdGl0bGUuaW5uZXJIVE1MIC0tPgo8IS0tIGBgYCAtLT4KCjwhLS1jaGFwdGVyOmVuZDoxMV9saWNlbnNlcy5SbWQtLT4KCiMgQ29sb3Bob24KCgoKCgpUaGUgMjAyMiBhbmQgMjAyNCBlZGl0aW9ucyBvZiB0aGlzIGJvb2sgd2VyZSBwcm9kdWNlIGluIFJTdHVkaW8gYW5kIHdpdGggdGhlIGBib29rZG93bmAgcGFja2FnZS4gQmVsb3cgYSBsaXN0aW5nIG9mIGluc3RhbGxlZCBwcm9ncmFtcyBhbmQgbGlicmFyaWVzLCB0aGUgb3BlcmF0aW5nIHN5c3RlbSwgYW5kIHRoZWlyIHNwZWNpZmljIHZlcnNpb25zLgoKCmBgYAojIyDilIAgU2Vzc2lvbiBpbmZvIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgAojIyAgc2V0dGluZyAgdmFsdWUKIyMgIHZlcnNpb24gIFIgdmVyc2lvbiA0LjMuMyAoMjAyNC0wMi0yOSkKIyMgIG9zICAgICAgIG1hY09TIFNvbm9tYSAxNC41CiMjICBzeXN0ZW0gICB4ODZfNjQsIGRhcndpbjIwCiMjICB1aSAgICAgICBYMTEKIyMgIGxhbmd1YWdlIChFTikKIyMgIGNvbGxhdGUgIGVuX1VTLlVURi04CiMjICBjdHlwZSAgICBlbl9VUy5VVEYtOAojIyAgdHogICAgICAgQW1lcmljYS9OZXdfWW9yawojIyAgZGF0ZSAgICAgMjAyNC0wNC0wNAojIyAgcGFuZG9jICAgMy4xLjEgQCAvQXBwbGljYXRpb25zL1JTdHVkaW8uYXBwL0NvbnRlbnRzL1Jlc291cmNlcy9hcHAvcXVhcnRvL2Jpbi90b29scy8gKHZpYSBybWFya2Rvd24pCiMjIAojIyDilIAgUGFja2FnZXMg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSACiMjICBwYWNrYWdlICAgICAgICAgICAqIHZlcnNpb24gZGF0ZSAoVVRDKSBsaWIgc291cmNlCiMjICBhc2twYXNzICAgICAgICAgICAgIDEuMi4wICAgMjAyMy0wOS0wMyBbMl0gQ1JBTiAoUiA0LjMuMCkKIyMgIGJvb2tkb3duICAgICAgICAgICogMC4zOC4xICAyMDI0LTAzLTI2IFsyXSBHaXRodWIgKHJzdHVkaW8vYm9va2Rvd25ANTBhMWMxZSkKIyMgIGJzbGliICAgICAgICAgICAgICAgMC42LjIgICAyMDI0LTAzLTIyIFsyXSBDUkFOIChSIDQuMy4yKQojIyAgY2FjaGVtICAgICAgICAgICAgICAxLjAuOCAgIDIwMjMtMDUtMDEgWzJdIENSQU4gKFIgNC4zLjApCiMjICBjaHJvbW90ZSAgICAgICAgICAgIDAuMi4wICAgMjAyNC0wMi0xMiBbMV0gQ1JBTiAoUiA0LjMuMikKIyMgIGNsaSAgICAgICAgICAgICAgICAgMy42LjIgICAyMDIzLTEyLTExIFsyXSBDUkFOIChSIDQuMy4wKQojIyAgY29sb3JzcGFjZSAgICAgICAgICAyLjEtMCAgIDIwMjMtMDEtMjMgWzJdIENSQU4gKFIgNC4zLjApCiMjICBjcmF5b24gICAgICAgICAgICAgIDEuNS4yICAgMjAyMi0wOS0yOSBbMl0gQ1JBTiAoUiA0LjMuMCkKIyMgIGNydWwgICAgICAgICAgICAgICAgMS40LjAgICAyMDIzLTA1LTE3IFsyXSBDUkFOIChSIDQuMy4wKQojIyAgY3VybCAgICAgICAgICAgICAgICA1LjIuMSAgIDIwMjQtMDMtMDEgWzJdIENSQU4gKFIgNC4zLjIpCiMjICBkYXRhLnRhYmxlICAgICAgICAgIDEuMTUuNCAgMjAyNC0wMy0zMCBbMV0gQ1JBTiAoUiA0LjMuMikKIyMgIGRpZ2VzdCAgICAgICAgICAgICAgMC42LjM1ICAyMDI0LTAzLTExIFsyXSBDUkFOIChSIDQuMy4yKQojIyAgZXZhbHVhdGUgICAgICAgICAgICAwLjIzICAgIDIwMjMtMTEtMDEgWzJdIENSQU4gKFIgNC4zLjApCiMjICBmYXN0bWFwICAgICAgICAgICAgIDEuMS4xICAgMjAyMy0wMi0yNCBbMl0gQ1JBTiAoUiA0LjMuMCkKIyMgIGZsZXh0YWJsZSAgICAgICAgICogMC45LjUgICAyMDI0LTAzLTA2IFsxXSBDUkFOIChSIDQuMy4yKQojIyAgZm9udEJpdHN0cmVhbVZlcmEgICAwLjEuMSAgIDIwMTctMDItMDEgWzJdIENSQU4gKFIgNC4zLjApCiMjICBmb250TGliZXJhdGlvbiAgICAgIDAuMS4wICAgMjAxNi0xMC0xNSBbMl0gQ1JBTiAoUiA0LjMuMCkKIyMgIGZvbnRxdWl2ZXIgICAgICAgICAgMC4yLjEgICAyMDE3LTAyLTAxIFsyXSBDUkFOIChSIDQuMy4wKQojIyAgZm9ybWF0UiAgICAgICAgICAgKiAxLjE0ICAgIDIwMjMtMDEtMTcgWzJdIENSQU4gKFIgNC4zLjApCiMjICBnZHRvb2xzICAgICAgICAgICAgIDAuMy43ICAgMjAyNC0wMy0wNSBbMl0gQ1JBTiAoUiA0LjMuMikKIyMgIGdmb250cyAgICAgICAgICAgICAgMC4yLjAgICAyMDIzLTAxLTA4IFsyXSBDUkFOIChSIDQuMy4wKQojIyAgZ2x1ZSAgICAgICAgICAgICAgICAxLjcuMCAgIDIwMjQtMDEtMDkgWzJdIENSQU4gKFIgNC4zLjApCiMjICBodG1sdG9vbHMgICAgICAgICAgIDAuNS44ICAgMjAyNC0wMy0yNSBbMl0gQ1JBTiAoUiA0LjMuMikKIyMgIGh0dHBjb2RlICAgICAgICAgICAgMC4zLjAgICAyMDIwLTA0LTEwIFsyXSBDUkFOIChSIDQuMy4wKQojIyAgaHR0cHV2ICAgICAgICAgICAgICAxLjYuMTUgIDIwMjQtMDMtMjYgWzJdIENSQU4gKFIgNC4zLjIpCiMjICBqcXVlcnlsaWIgICAgICAgICAgIDAuMS40ICAgMjAyMS0wNC0yNiBbMl0gQ1JBTiAoUiA0LjMuMCkKIyMgIGpzb25saXRlICAgICAgICAgICAgMS44LjggICAyMDIzLTEyLTA0IFsyXSBDUkFOIChSIDQuMy4wKQojIyAga2FibGVFeHRyYSAgICAgICAgKiAxLjQuMCAgIDIwMjQtMDEtMjQgWzFdIENSQU4gKFIgNC4zLjIpCiMjICBrbml0ciAgICAgICAgICAgICAqIDEuNDUgICAgMjAyMy0xMC0zMCBbMV0gQ1JBTiAoUiA0LjMuMCkKIyMgIGxhdGVyICAgICAgICAgICAgICAgMS4zLjIgICAyMDIzLTEyLTA2IFsyXSBDUkFOIChSIDQuMy4wKQojIyAgbGlmZWN5Y2xlICAgICAgICAgICAxLjAuNCAgIDIwMjMtMTEtMDcgWzJdIENSQU4gKFIgNC4zLjApCiMjICBtYWdyaXR0ciAgICAgICAgICAgIDIuMC4zICAgMjAyMi0wMy0zMCBbMl0gQ1JBTiAoUiA0LjMuMCkKIyMgIG1pbWUgICAgICAgICAgICAgICAgMC4xMiAgICAyMDIxLTA5LTI4IFsyXSBDUkFOIChSIDQuMy4wKQojIyAgbXVuc2VsbCAgICAgICAgICAgICAwLjUuMSAgIDIwMjQtMDQtMDEgWzFdIENSQU4gKFIgNC4zLjIpCiMjICBvZmZpY2VyICAgICAgICAgICAgIDAuNi41ICAgMjAyNC0wMi0yNCBbMl0gQ1JBTiAoUiA0LjMuMikKIyMgIG9wZW5zc2wgICAgICAgICAgICAgMi4xLjEgICAyMDIzLTA5LTI1IFsyXSBDUkFOIChSIDQuMy4wKQojIyAgcHJvY2Vzc3ggICAgICAgICAgICAzLjguNCAgIDIwMjQtMDMtMTYgWzJdIENSQU4gKFIgNC4zLjIpCiMjICBwcm9taXNlcyAgICAgICAgICAgIDEuMi4xICAgMjAyMy0wOC0xMCBbMl0gQ1JBTiAoUiA0LjMuMCkKIyMgIHBzICAgICAgICAgICAgICAgICAgMS43LjYgICAyMDI0LTAxLTE4IFsyXSBDUkFOIChSIDQuMy4wKQojIyAgUjYgICAgICAgICAgICAgICAgICAyLjUuMSAgIDIwMjEtMDgtMTkgWzJdIENSQU4gKFIgNC4zLjApCiMjICByYWdnICAgICAgICAgICAgICAgIDEuMy4wICAgMjAyNC0wMy0xMyBbMl0gQ1JBTiAoUiA0LjMuMikKIyMgIFJjcHAgICAgICAgICAgICAgICAgMS4wLjEyICAyMDI0LTAxLTA5IFsyXSBDUkFOIChSIDQuMy4wKQojIyAgcmxhbmcgICAgICAgICAgICAgICAxLjEuMyAgIDIwMjQtMDEtMTAgWzJdIENSQU4gKFIgNC4zLjApCiMjICBybWFya2Rvd24gICAgICAgICAqIDIuMjYuMSAgMjAyNC0wMy0yNiBbMl0gR2l0aHViIChyc3R1ZGlvL3JtYXJrZG93bkBlZTY5ZDU5KQojIyAgcnN0dWRpb2FwaSAgICAgICAgICAwLjE2LjAgIDIwMjQtMDMtMjQgWzJdIENSQU4gKFIgNC4zLjIpCiMjICBzYXNzICAgICAgICAgICAgICAgIDAuNC45ICAgMjAyNC0wMy0xNSBbMl0gQ1JBTiAoUiA0LjMuMikKIyMgIHNjYWxlcyAgICAgICAgICAgICAgMS4zLjAgICAyMDIzLTExLTI4IFsyXSBDUkFOIChSIDQuMy4wKQojIyAgc2Vzc2lvbmluZm8gICAgICAgICAxLjIuMiAgIDIwMjEtMTItMDYgWzJdIENSQU4gKFIgNC4zLjApCiMjICBzaGlueSAgICAgICAgICAgICAgIDEuOC4xICAgMjAyNC0wMy0yNiBbMl0gQ1JBTiAoUiA0LjMuMikKIyMgIHN0cmluZ2kgICAgICAgICAgICAgMS44LjMgICAyMDIzLTEyLTExIFsyXSBDUkFOIChSIDQuMy4wKQojIyAgc3RyaW5nciAgICAgICAgICAgICAxLjUuMSAgIDIwMjMtMTEtMTQgWzJdIENSQU4gKFIgNC4zLjApCiMjICBzdmdsaXRlICAgICAgICAgICAgIDIuMS4zICAgMjAyMy0xMi0wOCBbMV0gQ1JBTiAoUiA0LjMuMCkKIyMgIHN5c3RlbWZvbnRzICAgICAgICAgMS4wLjYgICAyMDI0LTAzLTA3IFsyXSBDUkFOIChSIDQuMy4yKQojIyAgdGV4dHNoYXBpbmcgICAgICAgICAwLjMuNyAgIDIwMjMtMTAtMDkgWzJdIENSQU4gKFIgNC4zLjApCiMjICB0aW55dGV4ICAgICAgICAgICAqIDAuNTAgICAgMjAyNC0wMy0xNiBbMl0gQ1JBTiAoUiA0LjMuMikKIyMgIHV1aWQgICAgICAgICAgICAgICAgMS4yLTAgICAyMDI0LTAxLTE0IFsyXSBDUkFOIChSIDQuMy4wKQojIyAgdmlyaWRpc0xpdGUgICAgICAgICAwLjQuMiAgIDIwMjMtMDUtMDIgWzJdIENSQU4gKFIgNC4zLjApCiMjICB3ZWJzaG90ICAgICAgICAgICAqIDAuNS41ICAgMjAyMy0wNi0yNiBbMV0gQ1JBTiAoUiA0LjMuMCkKIyMgIHdlYnNob3QyICAgICAgICAgICogMC4xLjEgICAyMDIzLTA4LTExIFsxXSBDUkFOIChSIDQuMy4wKQojIyAgd2Vic29ja2V0ICAgICAgICAgICAxLjQuMSAgIDIwMjEtMDgtMTggWzFdIENSQU4gKFIgNC4zLjApCiMjICB4ZnVuICAgICAgICAgICAgICAgIDAuNDMgICAgMjAyNC0wMy0yNSBbMl0gQ1JBTiAoUiA0LjMuMikKIyMgIHhtbDIgICAgICAgICAgICAgICAgMS4zLjYgICAyMDIzLTEyLTA0IFsyXSBDUkFOIChSIDQuMy4wKQojIyAgeHRhYmxlICAgICAgICAgICAgICAxLjgtNCAgIDIwMTktMDQtMjEgWzJdIENSQU4gKFIgNC4zLjApCiMjICB5YW1sICAgICAgICAgICAgICAgIDIuMy44ICAgMjAyMy0xMi0xMSBbMl0gQ1JBTiAoUiA0LjMuMCkKIyMgIHppcCAgICAgICAgICAgICAgICAgMi4zLjEgICAyMDI0LTAxLTI3IFsyXSBDUkFOIChSIDQuMy4yKQojIyAKIyMgIFsxXSAvVXNlcnMvc2xhYW4zL0xpYnJhcnkvUi94ODZfNjQvNC4zL2xpYnJhcnkKIyMgIFsyXSAvTGlicmFyeS9GcmFtZXdvcmtzL1IuZnJhbWV3b3JrL1ZlcnNpb25zLzQuMy14ODZfNjQvUmVzb3VyY2VzL2xpYnJhcnkKIyMgCiMjIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgApgYGAKCjwhLS0gYGBge2pzLCBlY2hvID0gRkFMU0V9IC0tPgo8IS0tIHRpdGxlPWRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdoZWFkZXInKTsgLS0+CjwhLS0gdGl0bGUuaW5uZXJIVE1MID0gJzxpbWcgc3JjPSJpbWcvX2hlYWRlcnMvYmFubmVyX21hbl9zdGFuZGluZ19kbmEucG5nIiBhbHQ9IkNvbG9mb24iPicgKyB0aXRsZS5pbm5lckhUTUwgLS0+CjwhLS0gYGBgIC0tPgoKPCEtLSBleGFtcGxlOiBodHRwczovL3llYXJib29rZGlzY292ZXJpZXMuY29tL3dwLWNvbnRlbnQvdXBsb2Fkcy8yMDE0LzA1L1dyaXRpbmdfYV9ZZWFyYm9va19Db2xvcGhvbi5wZGYgLS0+CjwhLS0gU1BFQ0lBTCBUSEFOS1M6IChUaGUgc3RhZmYgd3JvdGUgYSBmZXcgcGFyYWdyYXBocyBhYm91dCB0aGUgeWVhciBhbmQgbWVudGlvbmVkIGEgdmFyaWV0eSAtLT4KPCEtLSBvZiBwZW9wbGUgd2hvIHdlcmUgaW5zdHJ1bWVudGFsIGluIHRoZSBzdWNjZXNzIG9mIHRoZWlyIHllYXJib29rLikgLS0+CjwhLS0gQ09WRVIgJiBFTkRTSEVFVFM6IFRoZSAyMDEzIFBpbm5hY2xlIGNvdmVyIGlzIGEgZm91ci1jb2xvciBsaXRob2dyYXBoLiBBbiBpcmlkZXNjZW50IGZvaWwgLS0+CjwhLS0gY292ZXJzIGEgcG9ydGlvbiBvZiB0aGUgdGhlbWUgZGVzaWduLiBUaGUgZW5kc2hlZXRzIGFyZSBzdGFuZGFyZCBzdG9jayBwYXBlci4gVGhlIHRoZW1lIC0tPgo8IS0tIGNvbmNlcHQgd2FzIGNyZWF0ZWQgYW5kIGV4cGFuZGVkIGJ5IHRoZSBlZGl0b3JpYWwgdGVhbSBhbmQgbWVtYmVycyBvZiB0aGUgMjAxMyBQaW5uYWNsZSAtLT4KPCEtLSBzdGFmZi4gQ292ZXIgYW5kIGVuZHNoZWV0cyB3ZXJlIGRlc2lnbmVkIGJ5IFBpbm5hY2xlIGNvLWVkaXRvcnMtaW4tY2hpZWYgUmVnYW4gQnJvd24gYW5kIC0tPgo8IS0tIEVsbGVuYSBTdWxsaXZhbiwgd2l0aCBpbnNwaXJhdGlvbiBwcm92aWRlZCBieSBhbiBlYXJseSBkZXNpZ24gZnJvbSBjby1yZWZlcmVuY2UgZWRpdG9yIC0tPgo8IS0tIEFtYW5kYSBGYXJyZXIuIC0tPgo8IS0tIFRZUEUgJiBDT0xPUiBUUkVBVE1FTlQ6IEJvZHkgY29weSB0aHJvdWdob3V0IHRoZSBib29rIGlzIHNldCBpbiBGcnV0aWdlciBMaWdodCAtLT4KPCEtLSBDb25kZW5zZWQgKDguNSBwdC4pIENhcHRpb25zIGFyZSBzZXQgaW4gRnJ1dGlnZXIgTGlnaHQgQ29uZGVuc2VkICg3LjUgcHQuKSBIZWFkbGluZSAtLT4KPCEtLSB0cmVhdG1lbnRzIGFyZSBkZXNpZ25lZCB3aXRoIHZhcmlhdGlvbnMgb2YgQUhKIE5hc2h2aWxsZSwgQXJubyBQcm8gYW5kIEZydXRpZ2VyLiBQaG90byAtLT4KPCEtLSBjcmVkaXRzIGFuZCBzcHJlYWQgY3JlZGl0cyBhcHBlYXIgaW4gRnJ1dGlnZXIgSXRhbGljICg2IHB0LikgLS0+CjwhLS0gRm9yIGNvbnNpc3RlbmN5LCBhIGNvbG9yIHBhbGV0dGUgd2FzIGNob3Nlbi4gSW4gYWRkaXRpb24gdG8gdGhlIHRyYWRpdGlvbmFsIGJsYWNrLCB0aGUgLS0+CjwhLS0gZm9sbG93aW5nIGNvbG9ycyBhcHBlYXIgdGhyb3VnaG91dCB0aGUgcHVibGljYXRpb246IFBhbnRvbmUgMTUxQywgUGFudG9uZSAzMDA1QywgUGFudG9uIC0tPgo8IS0tIDI5ODVDLCBQYW50b25lIDExNUMsIFBhbnRvbmUgMzc2QywgUGFudG9uZSAzNjNDLCBQYW50b25lIDI2NkMsIFBhbnRvbmUgMTg1QyBhbmQgLS0+CjwhLS0gUGFudG9uZSBDb29sIEdyZXkgN0MuIC0tPgo8IS0tIFBVQkxJU0hJTkc6IFZvbHVtZSAxMDcgb2YgdGhlIFBpbm5hY2xlIHdhcyBkZXNpZ25lZCBhbmQgcHJvZHVjZWQgYnkgdGhlIDIwMTMgUGlubmFjbGUgLS0+CjwhLS0gc3RhZmYuIFRoZSA0NTYtcGFnZSwgYWxsLWNvbG9yIFBpbm5hY2xlIGlzIHByaW50ZWQgb24gODAgbGIuIGdsb3NzIHBhcGVyIGJ5IEhlcmZmIEpvbmVzIC0tPgo8IS0tIFB1Ymxpc2hpbmcgQ28uIGluIEthbnNhcyBDaXR5LCBNTy4gQXBwcm94aW1hdGVseSAzLDAwMCBjb3BpZXMgd2VyZSBwcmUtb3JkZXJlZCBmb3IgJDUyLiAtLT4KPCEtLSBBbnkgZXh0cmEgY29waWVzIHdlcmUgc29sZCBmb3IgJDYwLiBBIDQ4LXBhZ2Ugc3VwcGxlbWVudCB3YXMgaW5jbHVkZWQgaW4gdGhpcyBwcmljZS4gVGhlIC0tPgo8IS0tIHB1YmxpY2F0aW9uIHdhcyBjcmVhdGVkIHVzaW5nIEFkb2JlIENTNS41IHNvZnR3YXJlIG9uIDQyIE1hY2ludG9zaCBkZXNrdG9wIGFuZCBsYXB0b3AgLS0+CjwhLS0gY29tcHV0ZXJzLiAtLT4KPCEtLSBQSE9UT0dSQVBIWTogUGlubmFjbGUgc3RhZmYgcGhvdG9ncmFwaGVycyBzaG90IGRpZ2l0YWwgcGhvdG9zIHVzaW5nIGZvdXIgTmlrb24gRDcwcywgLS0+CjwhLS0gdHdvIE5pa29uIEQ4MHMgYW5kIG9uZSBOaWtvbiBENDAuIFNwb3J0IGdyb3VwIHBob3RvcyB3ZXJlIHNob3QgYnkgUHJlc3RpZ2UgUG9ydHJhaXRzLCAtLT4KPCEtLSBhbmQgY2x1YiBhbmQgZ3JvdXAgcGhvdG9zIHdlcmUgc2hvdCBieSBib3RoIFByZXN0aWdlIFBvcnRyYWl0cyBhbmQgUGlubmFjbGUgeWVhcmJvb2sgc3RhZmYgLS0+CjwhLS0gcGhvdG9ncmFwaGVycy4gU29tZSBzdWJtaXR0ZWQgcGhvdG9zIGFwcGVhciB0aHJvdWdob3V0IHRoZSBib29rIGFzIHdlbGwuIC0tPgo8IS0tIEVESVRPUlPigJkgTk9URTogKEEgc3BlY2lhbCBub3RlIGZyb20gdGhlIGNvLWVkaXRvcnMtaW4tY2hpZWYgd2FzIGluY2x1ZGVkIGhlcmUuIFRoZSB5ZWFyYm9vayAtLT4KPCEtLSBzdGFmZiBwaG90byB3aXRoIG5hbWVzIGFuZCBzdGFmZiBwb3NpdGlvbnMgd2FzIGluY2x1ZGVkIG9uIHRoZSBzcHJlYWQgd2l0aCB0aGUgY29sb3Bob24uKSAtLT4KCjwhLS1jaGFwdGVyOmVuZDoxMl9jb2xvcGhvbi5SbWQtLT4KCgojIFJlZmVyZW5jZXMgey19CgoKPCEtLWNoYXB0ZXI6ZW5kOjEzX3JlZmVyZW5jZXMuUm1kLS0+Cgo=